上源码,请大人们一定帮忙看看!!!!!!!!!!!!
final class DES
{
/* Tables defined in the Data Encryption Standard documents */ /* initial permutation IP */
private static final int ip[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
}; /* final permutation IP^-1 */
private static final int fp[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* expansion operation matrix */ private static final int ei[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/* permuted choice table (key) */
private static final int pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
}; /* number left rotations of pc1 */
private static final int totrot[] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
}; /* permuted choice key (table) */
private static final int pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
}; /* The famous S-boxes */
private static final int sbox[][][] =
{
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
}
};
/* 32-bit permutation function P used on the output of the S-boxes */
private static final int p32i[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* End of DES-defined tables */ /**key64 saves the original 64-bit key*/
private char[] key64 = new char[8]; /**key56 saves the compressed and extended 56-bit key,key64->key56*/
private int[] key56; private int[][] keys16 = new int[16][48]; /**it saves the input data*/
private char[] sourcechar = new char[8]; /**it saves the binary matrix transformed from origin array*/
private int[] source; /**it saves the 0-32 bits of the source*/
private int[] sourceLeft = new int[32]; /**it saves the 33-63 bits of the source*/
private int[] sourceRight = new int[32]; private int[] result; /**cryptography saves the result of the */
private char[] resultchar = new char[8];
final class DES
{
/* Tables defined in the Data Encryption Standard documents */ /* initial permutation IP */
private static final int ip[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
}; /* final permutation IP^-1 */
private static final int fp[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
/* expansion operation matrix */ private static final int ei[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
/* permuted choice table (key) */
private static final int pc1[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
}; /* number left rotations of pc1 */
private static final int totrot[] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
}; /* permuted choice key (table) */
private static final int pc2[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
}; /* The famous S-boxes */
private static final int sbox[][][] =
{
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
},
{{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}
}
};
/* 32-bit permutation function P used on the output of the S-boxes */
private static final int p32i[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
/* End of DES-defined tables */ /**key64 saves the original 64-bit key*/
private char[] key64 = new char[8]; /**key56 saves the compressed and extended 56-bit key,key64->key56*/
private int[] key56; private int[][] keys16 = new int[16][48]; /**it saves the input data*/
private char[] sourcechar = new char[8]; /**it saves the binary matrix transformed from origin array*/
private int[] source; /**it saves the 0-32 bits of the source*/
private int[] sourceLeft = new int[32]; /**it saves the 33-63 bits of the source*/
private int[] sourceRight = new int[32]; private int[] result; /**cryptography saves the result of the */
private char[] resultchar = new char[8];
* Encrypts/Decrypts plain text, this constructor collects
* all the parameters and makes essential transaction.
* @param encrypt choose to encrypt or decrypt
* @param key input the key
* @param plaintext plaintext
*/
public DES(char[] key, char[] originchar)
{
setKeyAndPlaintext(key, originchar);
} /**
* use 64-bit inputted key to make 16 keys of 48-bit
*/
private void makeKey()
{
int[] intKey64Temp = convert(key64); //convert 64-bit key from char to int
key56 = permutation(intKey64Temp, pc1); //use pc1 to permute, get 56 bit key
intKey64Temp = null;
int[] intKeyLeft = new int[28];
int[] intKeyRight = new int[28];
for(int i=0; i<28;i++) // seperate key56 into two parts
{
intKeyLeft[i] = key56[i];
intKeyRight[i] = key56[i+28];
}
for(int i =0; i<16;i++) //make 16 keys
{
//bitwise operate
int temp1 = intKeyLeft[0]; //save the first left bit of intKeyLeft
int temp2 = intKeyRight[0]; //save the first left bit of intKeyRight
for(int j=0;j<27;j++) //shift two parts of key
{
intKeyLeft[j] = intKeyLeft[j+1];
intKeyRight[j] = intKeyRight[j+1];
}
intKeyLeft[27] = temp1;
intKeyRight[27] = temp2;
if(totrot[i]==2) //if totrot[i]==2, do shift again
{
temp1 = intKeyLeft[0];
temp2 = intKeyRight[0];
for (int j = 0; j < 27; j++)
{
intKeyLeft[j] = intKeyLeft[j + 1];
intKeyRight[j] = intKeyRight[j + 1];
}
intKeyLeft[27] = temp1;
intKeyRight[27] = temp2;
}
for(int j=0; j<28; j++) //joint left and right parts to a key
{
key56[j] = intKeyLeft[j];
key56[j+28] = intKeyRight[j];
}
keys16[i] = permutation(key56,pc2);
}
} /**
* This method is to do most work of encryption.
* @param encrypt choose to encrypt or decrypt
*/
public char[] excute(boolean encrypt)
{
initialPermutation();
seperateSource();
if(encrypt)
encrypt();
else
decrypt();
combineResult();
finalPermutation();
makeResult();
return resultchar;
} /**
* to do initial permutation
* this is not essential part of the algorithm
*/
private void initialPermutation()
{
source = permutation(source,ip);
} /**
* to do final permutation
* this is not essential part of the algorithm
*/
private void finalPermutation()
{
result = permutation(result,fp);
} /**
* Do enctyption, using key 0-16
*/
private void encrypt()
{
for(int i=0;i<16;i++)
{
f(keys16[i]);
}
}
/**
* Do decryption, using key 16-0
*/
private void decrypt()
{
for(int i=15;i>=0;i--)
f(keys16[i]);
} private void f(int[] key)
{
//extend the right part from 32bits to 48bits
int[] extended = permutation(sourceRight,ei);
for(int i=0;i<key.length;i++)
extended[i]^=key[i];
int[] sub = new int[32];
for(int i=0;i<8;i++) //mapping by s-box
{
int row, column;
row = extended[i*6]*2 +extended[i*6+5];
column = extended[i*6+1]*8 + extended[i*6+2]*4
+ extended[i*6+3]*2 + extended[i*6+4];
sub[i*4] = (sbox[i][row][column]/8)%2;
sub[i*4+1] = (sbox[i][row][column]/4)%2;
sub[i*4+2] = (sbox[i][row][column]/2)%2;
sub[i*4+3] = sbox[i][row][column]%2;
}
sub = permutation(sub,p32i); // P permutation
int[] temp = new int[32];
for(int i=0;i<32;i++)
temp[i] = sourceLeft[i];
for(int i=0;i<32;i++)
sourceLeft[i] = sourceRight[i];
for(int i=0;i<32;i++)
{
sourceRight[i] = temp[i]^sub[i];
}
} /**
* Convert char array/matrix to intteger array/matrix
* <p> char 8bit 0 1 2 3 4 5 6 7</p>
* <p> int[] 8*i 8*i+1 8*i+2 8*i+3 8*i+4 8*i+5 8*i+6 8*i+7</p>
* @param ch it's a char array(the plaintext or key input)
* @return bit[] has 64 or 48 members which is 1 or 0
*/
private int[] convert(char[] ch)
{
int bit[] = new int[ch.length*8];
for(int i=0;i<ch.length;i++)
{
int temp = (int)ch[i];
bit[8*i] = (temp/128)%2;
bit[8*i+1] = (temp/64)%2;
bit[8*i+2] = (temp/32)%2;
bit[8*i+3] = (temp/16)%2;
bit[8*i+4] = (temp/8)%2;
bit[8*i+5] = (temp/4)%2;
bit[8*i+6] = (temp/2)%2;
bit[8*i+7] = temp%2;
}
return bit;
} /**
* Permutation by template matrix defined at the beginning
* @param initial the original matrix to be transformed
* @param perm the mapping matrix this permutation used
* @return the final transformed matrix
*/
private int[] permutation(int[] initial, int[] perm)
{
int[] result = new int[perm.length];
for(int i=0; i<result.length; i++)
{
result[i]=initial[perm[i]-1];
}
return result;
} /**
* Seperate source 64bits array into 2 32bits arrays
*/
private void seperateSource()
{
for(int i=0;i<32;i++)
{
sourceLeft[i]=source[i];
sourceRight[i]=source[i+32];
}
} /**
* Combine the two parts of result to a 64bits array
*/
private void combineResult()
{
result = new int[64];
for(int i=0;i<32;i++)
{
result[i] = sourceLeft[i];
result[i+32] = sourceRight[i];
}
} /**
* Convert int result matrix to char array
*/
private void makeResult()
{
for(int i=0;i<8;i++)
{
int x =
result[8*i]*128 + result[8*i+1]*64 + result[8*i+2]*32 +
result[8*i+3]*16 +result[8*i+4]*8 + result[8*i+5]*4 +
result[8*i+6]*2 + result[8*i+7];
resultchar[i]=(char)x;
}
}
/**
* Set to essential parameters of this encryotion
* @param key char array
* @param originchar plaintext or cryptography, also char array
*/
public void setKeyAndPlaintext(char[] key, char[] originchar)
{
//1. chech if these two input arrays need to be paded
if(key.length<8) //if the key less than 64-bits
{
for(int i=0;i<8;i++) //copy key
key64[i] = key[i];
for(int i=key.length;i<8;i++) //add bits with 1
key64[i] = 0xF;
}
else //only copy 64 bits
{
for(int i=0;i<8;i++)
key64[i] = key[i];
}
//2. compute 16 keys
makeKey();
//3. chech if the data need to be cut or.....
if(originchar.length<=8)
{
sourcechar = new char[8];
for(int i=0;i<originchar.length;i++)
sourcechar[i] = originchar[i];
for(int i=originchar.length;i<8;i++)
sourcechar[i] = 0;
}
else
{
for(int i=0;i<8;i++)
sourcechar[i] = originchar[i];
}
//4. convert source from char to integer
source = convert(sourcechar);
} private void printMatrix(int[] data)
{
for(int i=0;i<(data.length/8);i++)
{
for(int j=0;j<8;j++)
System.out.print(data[i*8+j]);
System.out.print("\n");
}
System.out.print("\n");
}
}
setKeyAndPlaintext方法首先处理key和明文这两个参数,然后先做makeKey(),生成16个key
加密基本是excute(boolean)函数调用其他的函数
IP
调用16次f()
FP基本思路就是这样,和书上写得流程应该是吻合的。就是现在不知道错在哪里。
我觉得最有可能出错的就是两个关键的方法f和makeKey,但具体不好定位,难道真的要我手算?5555555555各位大哥,救救我吧!