com.scudata.common.DES Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of esproc Show documentation
Show all versions of esproc Show documentation
SPL(Structured Process Language) A programming language specially for structured data computing.
package com.scudata.common;
/* This class implements the DES arithmetic.
* Notice: the shift operation to a byte value is hard to control, because Java
* treat the byte type as a signed integer. In order to avoid the problem, the
* process in the program is based on character type.
*/
public class DES {
private static final int DIR_ENCRYPT = 1;
private static final int DIR_DECRYPT = 2;
// S-function table
private static final char sFunctionTable[][] = {
// S-1
{
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
},
// S-2
{
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
},
// S-3
{
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
},
// S-4
{
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
},
// S-5
{
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
},
// S-6
{
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
},
// S-7
{
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
},
// S-8
{
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}
};
private char[] codedKey = new char[8];
//Creates a DES object whose key is supplied by a string.
public byte[] pKey(byte[] key) {
int len = key.length;
if( len == 8 ) return key;
byte[] bb = new byte[8];
if( len<8 ) {
System.arraycopy(key, 0, bb, 0, len);
return bb;
} else {
for(int i=0; i>24);
buf[1] = (byte)(len>>16);
buf[2] = (byte)(len>>8);
buf[3] = (byte)len;
//System.out.println( (int)buf[0] + "," + (int)buf[1] + "," + (int)buf[2] + "," + (int)buf[3] );
System.arraycopy(s, 0, buf, 4, len);
return desProcess1(dir, buf, 4+l);
} else {
byte[] buf1 = desProcess1(dir, s, l);
//System.out.println( (int)buf1[0] + "," + (int)buf1[1] + "," + (int)buf1[2] + "," + (int)buf1[3] );
int len = ((buf1[0]&0xff)<<24) + ((buf1[1]&0xff)<<16) + ((buf1[2]&0xff)<<8) + (buf1[3]&0xff);
//System.out.println( "len=" + len );
byte[] buf2 = new byte[len];
System.arraycopy(buf1, 4, buf2, 0, len);
return buf2;
}
}
private byte[] desProcess1(int dir, byte[] source, int l)
throws Exception
{
//Convert the byte array to a character array.
char[] srcBuffer = convertByteToChar(source, l);
//Encrypt or decrypt the character array.
char[] destBuffer = desProcess(dir, srcBuffer, l);
//Convert the result character array to a byte array.
byte[] dest = convertCharToByte(destBuffer, destBuffer.length);
return dest;
}
//Encrypts or decrypts the specified part of a character array.
private char[] desProcess(int dir, char[] s, int l) throws Exception
{
//Compute the length of the result.
int rl = (s.length / 8) * 8 + (s.length % 8 == 0 ? 0 : 8);
//Allocate memory for the result.
char[] dest = new char[rl];
// Allocate a 8 bytes buffer for internal processing, because
// DES arithmetic process data 8 bytes by 8 bytes.
char[] buffer = new char[8];
int offset = 0;
while(l > 0) {
//Copy the source data to the buffer. If the length of
// source data is less then 8 bytes, fill the buffer with 0.
System.arraycopy(s, offset, buffer, 0, l > 8 ? 8 : l);
for (int i = l; i < 8; i++) {
buffer[i] = 0x0;
}
//Encrypt or decrypt this 8 characters.
desProcess8chars(dir, buffer);
System.arraycopy(buffer, 0, dest, offset, 8);
offset += 8;
l -= 8;
}
return dest;
}
//Encrypts or decrypts 8 characters supplied by a character array.
private void desProcess8chars(int dir, char[] s) throws Exception
{
char[] keyCopy = new char[8];
int[] encryptLoop = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
int[] decryptLoop = {1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1};
int[] loop;
char[] k = new char[6];
char c;
if (dir == DIR_ENCRYPT) {
loop = encryptLoop;
} else {
loop = decryptLoop;
}
doFirstChange(s);
System.arraycopy(codedKey, 0, keyCopy, 0, 8);
for (int i = 0; i < 16; ++i) {
setKey(dir, keyCopy, loop[i], k);
doMut(s, k);
}
for(int i = 0; i < 4; ++i) {
c = s[i + 4];
s[i + 4] = s[i];
s[i] = c;
}
doLastChange(s);
}
//Processes the original key supplied by a byte array to its final format.
private void doKey(byte[] key) throws Exception {
char[] charBuffer = convertByteToChar(key, key.length);
doKey(charBuffer);
}
//Processes the original key supplied by a character array to its final format.
private void doKey(char[] key) throws Exception {
if (key.length != 8) {
throw new Exception("Invalid key length:" + key.length);
}
for (int i = 0; i < 8; i++) {
if (key[i] > 255) {
throw new Exception("Invalid character found in the des key");
}
}
char[] t = new char[8];
for (int i = 0; i < 8; ++i) {
t[i] = 0;
}
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
t[7-j] |= (((key[i] & (0x01 << j)) >> j) << i) & 0xff;
}
}
for (int i = 0; i < 4; i++) {
codedKey[i] = t[i];
codedKey[i + 4] = t[6-i];
}
codedKey[3] &= 0xf0;
codedKey[7] = (char)(((codedKey[7] & 0x0f) << 4) & 0xff);
}
private void doFirstChange(char[] s) {
char[] t = new char[8];
for (int i = 0; i < 8; ++i) {
t[i] = 0;
}
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
t[7-j] |= (((s[i] >> j) & 0x01 ) << i) & 0xff;
}
}
for (int i = 0; i < 4; ++i) {
s[i] = t[2 * i + 1];
s[i + 4] = t[2 * i];
}
}
private void doLastChange(char[] s) {
char[] t = new char[8];
for(int i = 0; i < 8; ++i) {
t[i] = 0;
}
for(int i = 0; i < 8; ++i) {
for(int j = 0; j < 4; ++j) {
t[i] |= ((s[j] << (7 - i)) & 0x80) >> (2 * j + 1);
t[i] |= ((s[j + 4] << (7 - i)) & 0x80) >> (2 * j);
}
}
/*for(int i = 0; i < 8; ++i) {
s[i] = t[i];
}*/
System.arraycopy(t, 0, s, 0, 8);
}
private void doLeft(char[] s, int n) {
doLeft(s, 0, n);
}
private void doLeft(char[] s, int offset, int n) {
char l, t;
l = (char)((0xff << (8 - n)) & 0xff);
t = (char)((s[offset] & l) >> 4);
s[offset + 3] |= t;
for(int i = offset; i < offset + 3; i++) {
s[i] <<= n;
s[i] &= 0xff;
t = (char)((s[i + 1] & l) >> (8 - n));
s[i] |= t;
}
s[offset + 3] <<= n;
s[offset + 3] &= 0xff;
}
private void doRight(char[] s, int n) {
doRight(s, 0, n);
}
private void doRight(char[] s, int offset, int n) {
for (int i = 0; i < n; ++i) {
char l0 = (char)(s[offset] & 1);
char l1 = (char)(s[offset + 1] & 1);
s[offset] >>= 1;
s[offset + 1] >>= 1;
s[offset + 1] |= (l0 << 7) & 0xff;
l0 = (char)(s[offset + 2] & 1);
s[offset + 2] >>= 1;
s[offset + 2] |= (l1 << 7) & 0xff;
s[offset + 3] >>= 1;
s[offset + 3] |= (l0 << 7) & 0xff;
if ((s[offset + 3] & 0xf) != 0) {
s[offset] |= 0x80;
s[offset + 3] &= 0xf0;
}
}
}
private void setKey(int dir, char[] key, int n, char[] k) {
for (int i = 0; i < 6; ++i) {
k[i] = 0;
}
if (dir == DIR_ENCRYPT) {
doLeft(key, n);
doLeft(key, 4, n);
}
k[0] = (char)( ((key[1] & 4) << 5)
| ((key[2] & 0x80) >> 1)
| (key[1] & 0X20)
| ((key[2] & 1) << 4)
| ((key[0] & 0X80) >> 4)
| ((key[0] & 8) >> 1)
| ((key[0] & 0x20) >> 4)
| ((key[3] & 0X10) >> 4) );
k[1] = (char)( ((key[1] & 2) << 6)
| ((key[0] & 4) << 4)
| ((key[2] & 8) << 2)
| ((key[1] & 0x40) >> 2)
| ((key[2] & 2) << 2)
| ((key[2] & 0x20) >> 3)
| ((key[1] & 0x10) >> 3)
| ((key[0] & 0X10) >> 4) );
k[2] = (char)( ((key[3] & 0x40) << 1)
| ((key[0] & 0x01) << 6)
| ((key[1] & 0x01) << 5)
| ((key[0] & 2) << 3)
| ((key[3] & 0x20) >> 2)
| ((key[2] & 0x10) >> 2)
| ((key[1] & 0x08) >> 2)
| ((key[0] & 0x40) >> 6) );
k[3] = (char)( ((key[5] & 0x08) << 4)
| ((key[6] & 0X01) << 6)
| (key[4] & 0X20)
| ((key[5] & 0x80) >> 3)
| ((key[6] & 0x20) >> 2)
| ((key[7] & 0x20) >> 3)
| ((key[4] & 0x40) >> 5)
| ((key[5] & 0x10) >> 4) );
k[4] = (char)( ((key[6] & 0x02) << 6)
| ((key[6] & 0x80) >> 1)
| ((key[4] & 0x08) << 2)
| (key[6] & 0x10)
| ((key[5] & 0X01) << 3 )
| ((key[6] & 0x08) >> 1)
| ((key[5] & 0x20) >> 4)
| ((key[7] & 0x10) >> 4) );
k[5] = (char)( ((key[4] & 0x04) << 5)
| ((key[7] & 0X80) >> 1)
| ((key[6] & 0x40)) >> 1
| ((key[5] & 0x04) << 2)
| ((key[6] & 0x04) << 1)
| ((key[4] & 0x01) << 2)
| ((key[4] & 0x80) >> 6)
| ((key[4] & 0x10) >> 4) );
if (dir == DIR_DECRYPT) {
doRight(key, n);
doRight(key, 4, n);
}
}
private void eExpand(char[] s, char[] r) {
r[0] = (char)( ((s[4 + 3] & 0x01) << 7)
| ((s[4 + 0] & 0xf8) >> 1)
| ((s[4 + 0] & 0x18) >> 3) );
r[1] = (char)( ((s[4 + 0] & 0x07) << 5)
| ((s[4 + 0] & 0x01) << 3)
| ((s[4 + 1] & 0x80) >> 3)
| ((s[4 + 1] & 0xe0) >> 5) );
r[2] = (char)( ((s[4 + 1] & 0x18) << 3)
| ((s[4 + 1] & 0x1f) << 1)
| ((s[4 + 2] & 0x80) >> 7) );
r[3] = (char)( ((s[4 + 1] & 0x01) << 7)
| ((s[4 + 2] & 0xf8) >> 1)
| ((s[4 + 2] & 0x18) >> 3) );
r[4] = (char)( ((s[4 + 2] & 0x07) << 5)
| ((s[4 + 2] & 0x01) << 3)
| ((s[4 + 3] & 0x80) >> 3)
| ((s[4 + 3] & 0xe0) >> 5) );
r[5] = (char)( ((s[4 + 3] & 0x18) << 3)
| ((s[4 + 3] & 0x1f) << 1)
| ((s[4 + 0] & 0x80) >> 7) );
}
private void pChange(char[] s) throws Exception
{
char[] t = null;
if (s == null || s.length < 4) {
throw new Exception("Invalid parameter");
}
t = new char[4];
t[0] = (char)( ((s[1] & 0x01) << 7)
| ((s[0] & 0x02) << 5)
| ((s[2] & 0x10) << 1)
| ((s[2] & 0x08) << 1)
| (s[3] & 0x08)
| ((s[1] & 0x10) >> 2)
| ((s[3] & 0x10) >> 3)
| ((s[2] & 0x80) >> 7) );
t[1] = (char)( (s[0] & 0x80)
| ((s[1] & 0x02) << 5)
| ((s[2] & 0x02) << 4)
| ((s[3] & 0x40) >> 2)
| (s[0] & 0x08)
| ((s[2] & 0x40) >> 4)
| (s[3] & 0x02)
| ((s[1] & 0x40) >> 6) );
t[2] = (char)( ((s[0] & 0x40) << 1)
| ((s[0] & 0x01) << 6)
| ((s[2] & 0x01) << 5)
| ((s[1] & 0x04) << 2)
| ((s[3] & 0x01) << 3)
| ((s[3] & 0x20) >> 3)
| ((s[0] & 0x20) >> 4)
| ((s[1] & 0x80) >> 7) );
t[3] = (char)( ((s[2] & 0x20) << 2)
| ((s[1] & 0x08) << 3)
| ((s[3] & 0x04) << 3)
| ((s[0] & 0x04) << 2)
| ((s[2] & 0x04) << 1)
| ((s[1] & 0x20) >> 3)
| ((s[0] & 0x10) >> 3)
| ((s[3] & 0x80) >> 7) );
for(int i = 0 ; i < 4; ++i) {
s[i] = t[i];
}
}
private char findS(char[] s, int ns) {
return findS(s, 0, ns);
}
private char findS(char[] s, int offset, int ns) {
int col, num, index = 0;
if (ns == 1 || ns == 5) {
col = ((s[offset] & 0x80) >> 6 ) | ((s[offset] & 0x04) >> 2);
num = (s[offset] & 0x78) >> 3;
index = col * 16 + num;
}
if (ns == 2 || ns == 6) {
col = (s[offset] & 0x02) | ((s[offset + 1] & 0x10) >> 4);
num = ((s[offset] & 0x01) << 3) | ((s[offset + 1] & 0xe0) >> 5);
index = col * 16 + num;
}
if (ns == 3 || ns == 7) {
col = ((s[offset + 1] & 0x08) >> 2)
| ((s[offset + 2] & 0x40) >> 6);
num = ((s[offset + 1] & 0x07) << 1)
| ((s[offset + 2] & 0x80) >> 7);
index = col * 16 + num;
}
if (ns == 4 || ns == 8) {
col = ((s[offset + 2] & 0x20) >> 4) | (s[offset + 2] & 0x01);
num = ((s[offset + 2] & 0x1e) >> 1);
index = col * 16 + num;
}
return sFunctionTable[ns-1][index];
}
private void doSFunction(char[] s, char[] r) {
r[0] = (char)((findS(s, 1) << 4) | findS(s, 2));
r[1] = (char)((findS(s, 3) << 4) | findS(s, 4));
r[2] = (char)((findS(s, 3, 5) << 4) | findS(s, 3, 6));
r[3] = (char)((findS(s, 3, 7) << 4) | findS(s, 3, 8));
}
private void fFunction(char[] s, char[] k, char[] m) throws Exception
{
char[] t = new char[6];
eExpand(s, t);
for (int i = 0; i < 6; ++i) {
t[i] ^= k[i];
}
doSFunction(t, m);
pChange(m);
}
private void doMut(char[] s, char[] k) throws Exception
{
char[] t = new char[4];
fFunction(s, k, t);
for (int i = 0; i < 4; ++i) {
t[i] ^= s[i];
s[i] = s[i + 4];
s[i + 4] = t[i];
}
}
//Convert the byte array to a character array.
static char[] convertByteToChar(byte[] source, int srclen) {
if (source == null)
return null;
int len = source.length;
if (len > srclen)
len = srclen;
char[] destChar = new char[len];
for (int i = 0; i < len; i++) {
if (source[i] >= 0)
destChar[i] = (char)source[i];
else
destChar[i] = (char)(256 + source[i]);
}
return destChar;
}
//Convert the character array to a byte array.
byte[] convertCharToByte(char[] source, int srclen) {
if (source == null)
return null;
int len = source.length;
if (len > srclen)
len = srclen;
byte[] dest = new byte[len];
for (int i = 0; i < len; i++)
dest[i] = (byte)source[i];
return dest;
}
public static void main(String[] args) throws Exception
{
DES des = new DES("1234567890");
String s = "abcdefgh?й??????ž?";
//for( int i = 0; i < 10; i++ )
// s += s;
byte[] bs = s.getBytes("utf-8");
System.out.println( "byte[] len=" + bs.length );
bs = des.encrypt(bs);
for( int i = 0; i < bs.length; i ++ ) {
System.out.print(bs[i]);
System.out.print(' ');
}
System.out.println();
bs = des.decrypt(bs);
System.out.println( bs.length );
s = new String(bs, "utf-8");
System.out.println( s + "," + s.length() );
//System.out.println(new Date());
//for (int i=0; i<100000; i++) {
// bs = des.encrypt(bs, 400);//?????ȣ?8?ı???
// bs = des.decrypt(bs, 400);
//}
//System.out.println(new Date());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy