Public class desutil {
Byte [] bytekey;
Public desutil (string strkey ){
This. bytekey = strkey. getbytes ();
}
// Declare a constant byte array
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}; // 64
Private Static final int [] ip_1 = {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}; // 64
Private Static final int [] pc_1 = {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}; // 56
Private Static final int [] pc_2 = {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}; // 48
Private Static final int [] e = {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}; // 48
Private Static final int [] P = {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}; // 32
Private Static final int [] [] [] s_box = {
{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_box [1]
{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_box [2]
{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_box [3]
{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_box [4]
{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_box [5]
{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_box [6]
{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_box [7]
{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} // s_box [8]
};
Private Static final int [] leftmove = {1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 1}; // left shift position list
Private byte [] unitdes (byte [] des_key, byte [] des_data, int flag ){
// Check whether the input parameter format is correct. If an error occurs, a null value is returned)
If (des_key.length! = 8) | (des_data.length! = 8)
| (Flag! = 1) & (flag! = 0 ))){
Throw new runtimeexception ("Data Format error! ");
}
Int flags = flag;
// Binary encryption key
Int [] keydata = new int [64];
// Encrypt binary data
Int [] encryptdata = new int [64];
// The byte array after the encryption operation is completed
Byte [] encryptcode = new byte [8];
// The Key is initially converted into a two-dimensional array.
Int [] [] keyarray = new int [16] [48];
// Convert the key byte array to a binary byte array
Keydata = readdatatobirnaryintarray (des_key );
// Convert the encrypted data byte array to a binary byte array
Encryptdata = readdatatobirnaryintarray (des_data );
// The initial test key is a two-dimensional key array.
Keyinitialize (keydata, keyarray );
// Perform encryption and decryption
Encryptcode = encrypt (encryptdata, flags, keyarray );
Return encryptcode;
}
// Initial key Array
Private void keyinitialize (INT [] key, int [] [] keyarray ){
Int I;
Int J;
Int [] K0 = new int [56];
// Special Note: XXX [IP [I]-1] and other similar Transformations
For (I = 0; I <56; I ++ ){
K0 [I] = Key [pc_1 [I]-1]; // key for PC-1 Transformation
}
For (I = 0; I <16; I ++ ){
Leftbitmove (K0, leftmove [I]);
// Special Note: XXX [IP [I]-1] and other similar Transformations
For (j = 0; j <48; j ++ ){
Keyarray [I] [J] = K0 [pc_2 [J]-1]; // generates a subkey keyarray [I] [J]
}
}
}
// Perform encryption and decryption
Private byte [] encrypt (INT [] timedata, int flag, int [] [] keyarray ){
Int I;
Byte [] encrypt = new byte [8];
Int flags = flag;
Int [] M = new int [64];
Int [] mip_1 = new int [64];
// Special Note: XXX [IP [I]-1] and other similar Transformations
For (I = 0; I <64; I ++ ){
M [I] = timedata [IP [I]-1]; // plaintext IP address conversion
}
If (flags = 1) {// Encryption
For (I = 0; I <16; I ++ ){
Loopf (M, I, flags, keyarray );
}
} Else if (flags = 0) {// decrypt
For (I = 15; I>-1; I --){
Loopf (M, I, flags, keyarray );
}
}
For (I = 0; I <64; I ++ ){
Mip_1 [I] = m [ip_1 [I]-1]; // IP-1 operation
}
Getencryptresultofbytearray (mip_1, encrypt );
// Return encrypted data
Return encrypt;
}
Private int [] readdatatobirnaryintarray (byte [] intdata ){
Int I;
Int J;
// Convert data into binary data and store it in an array
Int [] intda = new int [8];
For (I = 0; I <8; I ++ ){
Intda [I] = intdata [I];
If (intda [I] <0 ){
Intda [I] ++ = 256;
Intda [I] %= 256;
}
}
Int [] intva = new int [64];
For (I = 0; I <8; I ++ ){
For (j = 0; j <8; j ++ ){
Intva [(I * 8) + 7)-J] = intda [I] % 2;
Intda [I] = intda [I]/2;
}
}
Return intva;
}
Private void leftbitmove (INT [] K, int offset ){
Int I;
// Cyclic shift operation function
Int [] C0 = new int [28];
Int [] D0 = new int [28];
Int [] C1 = new int [28];
Int [] d1 = new int [28];
For (I = 0; I <28; I ++ ){
C0 [I] = K [I];
D0 [I] = K [I + 28];
}
If (offset = 1 ){
For (I = 0; I <27; I ++) {// shifts the left of a loop
C1 [I] = C0 [I + 1];
D1 [I] = D0 [I + 1];
}
C1 [27] = C0 [0];
D1 [27] = D0 [0];
} Else if (offset = 2 ){
For (I = 0; I <26; I ++) {// shifts two places to the left of the loop
C1 [I] = C0 [I + 2];
D1 [I] = D0 [I + 2];
}
C1 [26] = C0 [0];
D1 [26] = D0 [0];
C1 [27] = C0 [1];
D1 [27] = D0 [1];
}
For (I = 0; I <28; I ++ ){
K [I] = c1 [I];
K [I + 28] = D1 [I];
}
}
Private void loopf (INT [] M, int times, int flag, int [] [] keyarray ){
Int I;
Int J;
Int [] L0 = new int [32];
Int [] R0 = new int [32];
Int [] L1 = new int [32];
Int [] R1 = new int [32];
Int [] Re = new int [48];
Int [] [] S = new int [8] [6];
Int [] sboxdata = new int [8];
Int [] svalue = new int [32];
Int [] Rp = new int [32];
For (I = 0; I <32; I ++ ){
L0 [I] = m [I]; // Initialization on the left of plaintext
R0 [I] = m [I + 32]; // initialize the right side of the plaintext
}
For (I = 0; I <48; I ++ ){
Re [I] = R0 [E [I]-1]; // extended by E transformation, from 32-bit to 48-bit
Re [I] = Re [I] + keyarray [times] [I]; // bitwise addition with keyarray [times] [I]
If (Re [I] = 2 ){
Re [I] = 0;
}
}
For (I = 0; I <8; I ++) {// 48 digits are divided into 8 groups
For (j = 0; j <6; j ++ ){
S [I] [J] = Re [(I * 6) + J];
}
// The following code goes through the S box to obtain 8 numbers
Sboxdata [I] = s_box [I] [(S [I] [0] <1) + s [I] [5] [(S [I] [1] <3)
+ (S [I] [2] <2) + (s [I] [3] <1) + s [I] [4];
// 8-digit conversion output binary
For (j = 0; j <4; j ++ ){
Svalue [(I * 4) + 3)-J] = sboxdata [I] % 2;
Sboxdata [I] = sboxdata [I]/2;
}
}
For (I = 0; I <32; I ++ ){
RP [I] = svalue [p [I]-1]; // after P Transformation
L1 [I] = R0 [I]; // move the right to the left
R1 [I] = l0 [I] + RP [I];
If (R1 [I] = 2 ){
R1 [I] = 0;
}
// Re-synthesize m and return the array m
// The left and right sides are not interchangeable during the last transformation. Two transformations are used here to achieve the same
If (flag = 0) & (Times = 0) | (flag = 1) & (Times = 15 ))){
M [I] = R1 [I];
M [I + 32] = L1 [I];
} Else {
M [I] = L1 [I];
M [I + 32] = R1 [I];
}
}
}
Private void getencryptresultofbytearray (INT [] data, byte [] value ){
Int I;
Int J;
// Convert the data in the array storing 64-bit binary data to eight integers (bytes)
For (I = 0; I <8; I ++ ){
For (j = 0; j <8; j ++ ){
Value [I] + = (data [(I <3) + J] <(7-j ));
}
}
For (I = 0; I <8; I ++ ){
Value [I] % = 256;
If (value [I]> 128 ){
Value [I]-= 255;
}
}
}
Private byte [] bytedataformat (byte [] data, int flag ){
Int Len = data. length;
Int padlen = 8-(LEN % 8 );
Int newlen = Len + padlen;
Byte [] newdata = new byte [newlen];
System. arraycopy (data, 0, newdata, 0, Len );
For (INT I = Len; I <newlen; I ++)
Newdata [I] = (byte) padlen;
Return newdata;
}
Public byte [] desencrypt (byte [] des_data, int flag ){
Byte [] format_key = bytedataformat (bytekey, flag );
Byte [] format_data = bytedataformat (des_data, flag );
Int datalen = format_data.length;
Int unitcount = datalen/8;
Byte [] result_data = new byte [datalen];
For (INT I = 0; I <unitcount; I ++ ){
Byte [] tmpkey = new byte [8];
Byte [] tmpdata = new byte [8];
System. arraycopy (format_key, 0, tmpkey, 0, 8 );
System. arraycopy (format_data, I * 8, tmpdata, 0, 8 );
Byte [] tmpresult = unitdes (tmpkey, tmpdata, flag );
System. arraycopy (tmpresult, 0, result_data, I * 8, 8 );
}
// Currently, the decryption process removes the padding generated during encryption.
Byte [] decryptbytearray = NULL;
If (flag = 0 ){
Int total_len = datalen;
Int delete_len = result_data [total_len-8-1];
Delete_len = (delete_len> = 1) & (delete_len <= 8 ))? Delete_len
: 0;
Decryptbytearray = new byte [total_len-delete_len-8];
Boolean del_flag = true;
For (int K = 0; k <delete_len; k ++ ){
If (delete_len! = Result_data [total_len-8-(k + 1)])
Del_flag = false;
}
If (del_flag = true ){
System. arraycopy (result_data, 0, decryptbytearray, 0, total_len
-Delete_len-8 );
}
}
Return (flag = 1 )? Result_data: decryptbytearray;
}
Public static void main (string [] ARGs ){
String key = "12345678 ";
String data = "don't tell anybody !! ";
Desutil = new desutil (key );
System. Err. println ("encrypted data:" + data );
// Encrypted byte ciphertext
Byte [] result = desutil. desencrypt (data. getbytes (), 1 );
System. Err. println ("encrypted data:" + new string (result ));
// Decrypt the byte-type ciphertext directly in the next sentence to restore it correctly
System. Err. println ("directly decrypts byte-type garbled characters :"
+ New string (desutil. desencrypt (result, 0) + "(correct )");
// However, when the byte ciphertext is converted to a string, and the string ciphertext is converted to a byte upon decryption, it cannot be restored correctly.
String STR = new string (result );
System. Err. println ("string-type garbled decryption :"
+ New string (desutil. desencrypt (Str. getbytes (), 0) + "(error )");
}
}
Running result: