|  |  |  |  | /*
 | 
					
						
							|  |  |  |  |  * *
 | 
					
						
							|  |  |  |  |  *  * @Project HM OA
 | 
					
						
							|  |  |  |  |  *  * @Name DesUtil
 | 
					
						
							|  |  |  |  |  *  * @Author 张剑峰
 | 
					
						
							|  |  |  |  |  *  * @Date 18-4-15 下午11:02
 | 
					
						
							|  |  |  |  |  *  * @Version v1.0.0
 | 
					
						
							|  |  |  |  |  *  * @Copyright @ 2017 云南道睿科技有限公司 All rights reserved.
 | 
					
						
							|  |  |  |  |  *
 | 
					
						
							|  |  |  |  |  */
 | 
					
						
							|  |  |  |  | package com.ynxbd.wx.utils;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import java.io.PrintWriter;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * @author Administrator
 | 
					
						
							|  |  |  |  |  * @version v1.0.0
 | 
					
						
							|  |  |  |  |  * @date Oct 10, 2009 11:20:32 AM
 | 
					
						
							|  |  |  |  |  */
 | 
					
						
							|  |  |  |  | public class DesHelper {
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     static final String NAME = "DES";
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     static final boolean IN = true, OUT = false;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     static final int debuglevel = 0;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     static final PrintWriter err = null;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private static final int ROUNDS = 16; // number of rounds
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private static final int BLOCK_SIZE = 8; // DES block size in bytes
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Table for PC2 permutations in key schedule computation.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     private static final int[] SKB = new int[8 * 64]; // blank final
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Table for S-boxes and permutations.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     private static final int[] SP_TRANS = new int[8 * 64]; // blank final
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
 | 
					
						
							|  |  |  |  |             '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     static {
 | 
					
						
							|  |  |  |  |         String cd = "D]PKESYM`UBJ\\@RXA`I[T`HC`LZQ"
 | 
					
						
							|  |  |  |  |                 + "\\PB]TL`[C`JQ@Y`HSXDUIZRAM`EK";
 | 
					
						
							|  |  |  |  |         int j, s, bit;
 | 
					
						
							|  |  |  |  |         int count = 0;
 | 
					
						
							|  |  |  |  |         int offset = 0;
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < cd.length(); i++) {
 | 
					
						
							|  |  |  |  |             s = cd.charAt(i) - '@';
 | 
					
						
							|  |  |  |  |             if (s != 32) {
 | 
					
						
							|  |  |  |  |                 bit = 1 << count++;
 | 
					
						
							|  |  |  |  |                 for (j = 0; j < 64; j++)
 | 
					
						
							|  |  |  |  |                     if ((bit & j) != 0)
 | 
					
						
							|  |  |  |  |                         SKB[offset + j] |= 1 << s;
 | 
					
						
							|  |  |  |  |                 if (count == 6) {
 | 
					
						
							|  |  |  |  |                     offset += 64;
 | 
					
						
							|  |  |  |  |                     count = 0;
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         //
 | 
					
						
							|  |  |  |  |         // build the SP_TRANS table
 | 
					
						
							|  |  |  |  |         //
 | 
					
						
							|  |  |  |  |         // The theory is that each bit position in each int of SP_TRANS is
 | 
					
						
							|  |  |  |  |         // set in exactly 32 entries. We keep track of set bits.
 | 
					
						
							|  |  |  |  |         //
 | 
					
						
							|  |  |  |  |         String spt = // [526 chars, 3156 bits]
 | 
					
						
							|  |  |  |  |                 "g3H821:80:H03BA0@N1290BAA88::3112aIH8:8282@0@AH0:1W3A8P810@22;22"
 | 
					
						
							|  |  |  |  |                         + "A18^@9H9@129:<8@822`?:@0@8PH2H81A19:G1@03403A0B1;:0@1g192:@919AA"
 | 
					
						
							|  |  |  |  |                         + "0A109:W21492H@0051919811:215011139883942N8::3112A2:31981jM118::A"
 | 
					
						
							|  |  |  |  |                         + "101@I88:1aN0<@030128:X;811`920:;H0310D1033@W980:8A4@804A3803o1A2"
 | 
					
						
							|  |  |  |  |                         + "021B2:@1AH023GA:8:@81@@12092B:098042P@:0:A0HA9>1;289:@1804:40Ph="
 | 
					
						
							|  |  |  |  |                         + "1:H0I0HP0408024bC9P8@I808A;@0@0PnH0::8:19J@818:@iF0398:8A9H0<13@"
 | 
					
						
							|  |  |  |  |                         + "001@11<8;@82B01P0a2989B:0AY0912889bD0A1@B1A0A0AB033O91182440A9P8"
 | 
					
						
							|  |  |  |  |                         + "@I80n@1I03@1J828212A`A8:12B1@19A9@9@8^B:0@H00<82AB030bB840821Q:8"
 | 
					
						
							|  |  |  |  |                         + "310A302102::A1::20A1;8";
 | 
					
						
							|  |  |  |  |         offset = 0;
 | 
					
						
							|  |  |  |  |         int k, c, param;
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < 32; i++) { // each bit position
 | 
					
						
							|  |  |  |  |             k = -1; // pretend the -1th bit was set
 | 
					
						
							|  |  |  |  |             bit = 1 << i;
 | 
					
						
							|  |  |  |  |             for (j = 0; j < 32; j++) { // each set bit
 | 
					
						
							|  |  |  |  |                 // Each character consists of two three-bit values:
 | 
					
						
							|  |  |  |  |                 c = spt.charAt(offset >> 1) - '0' >> (offset & 1) * 3 & 7;
 | 
					
						
							|  |  |  |  |                 offset++;
 | 
					
						
							|  |  |  |  |                 if (c < 5) {
 | 
					
						
							|  |  |  |  |                     // value 0-4 indicate a set bit 1-5 positions from
 | 
					
						
							|  |  |  |  |                     // previous set bit
 | 
					
						
							|  |  |  |  |                     k += c + 1;
 | 
					
						
							|  |  |  |  |                     SP_TRANS[k] |= bit;
 | 
					
						
							|  |  |  |  |                     continue;
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |                 // other values take at least an additional parameter:
 | 
					
						
							|  |  |  |  |                 // the next value in the sequence.
 | 
					
						
							|  |  |  |  |                 param = spt.charAt(offset >> 1) - '0' >> (offset & 1) * 3 & 7;
 | 
					
						
							|  |  |  |  |                 offset++;
 | 
					
						
							|  |  |  |  |                 if (c == 5) {
 | 
					
						
							|  |  |  |  |                     // bit set param+6 positions from previous set bit
 | 
					
						
							|  |  |  |  |                     k += param + 6;
 | 
					
						
							|  |  |  |  |                     SP_TRANS[k] |= bit;
 | 
					
						
							|  |  |  |  |                 } else if (c == 6) {
 | 
					
						
							|  |  |  |  |                     // bit set param*64 + 1 positions from previous set bit
 | 
					
						
							|  |  |  |  |                     k += (param << 6) + 1;
 | 
					
						
							|  |  |  |  |                     SP_TRANS[k] |= bit;
 | 
					
						
							|  |  |  |  |                 } else {
 | 
					
						
							|  |  |  |  |                     // should skip param*64 positions, then process next value
 | 
					
						
							|  |  |  |  |                     // which will be in the range 0-4.
 | 
					
						
							|  |  |  |  |                     k += param << 6;
 | 
					
						
							|  |  |  |  |                     j--;
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // utility static methods (from cryptix.util.core ArrayUtil and Hex classes)
 | 
					
						
							|  |  |  |  |     // ...........................................................................
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Compares two byte arrays for equality.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @return true if the arrays have identical contents
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static boolean areEqual(byte[] a, byte[] b) {
 | 
					
						
							|  |  |  |  |         int aLength = a.length;
 | 
					
						
							|  |  |  |  |         if (aLength != b.length)
 | 
					
						
							|  |  |  |  |             return false;
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < aLength; i++)
 | 
					
						
							|  |  |  |  |             if (a[i] != b[i])
 | 
					
						
							|  |  |  |  |                 return false;
 | 
					
						
							|  |  |  |  |         return true;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Decrypt exactly one block of ciphertext.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param in         The ciphertext.
 | 
					
						
							|  |  |  |  |      * @param inOffset   Index of in from which to start considering data.
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for decryption.
 | 
					
						
							|  |  |  |  |      * @return The plaintext generated from a ciphertext using the session key.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static char[] blockDecrypt1(char[] in, int inOffset,
 | 
					
						
							|  |  |  |  |                                           Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         IP(L_R);
 | 
					
						
							|  |  |  |  |         decrypt(L_R, sessionKey);
 | 
					
						
							|  |  |  |  |         FP(L_R);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         return new char[]{(char) L, (char) (L >> 8),
 | 
					
						
							|  |  |  |  |                 (char) (L >> 16), (char) (L >> 24), (char) R, (char) (R >> 8),
 | 
					
						
							|  |  |  |  |                 (char) (R >> 16), (char) (R >> 24)};
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     protected static byte[] blockDecrypt(byte[] in, int inOffset,   Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         IP(L_R);
 | 
					
						
							|  |  |  |  |         decrypt(L_R, sessionKey);
 | 
					
						
							|  |  |  |  |         FP(L_R);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         return new byte[]{(byte) L, (byte) (L >> 8),
 | 
					
						
							|  |  |  |  |                 (byte) (L >> 16), (byte) (L >> 24), (byte) R, (byte) (R >> 8),
 | 
					
						
							|  |  |  |  |                 (byte) (R >> 16), (byte) (R >> 24)};
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Encrypt exactly one block of plaintext.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param in         The plaintext.
 | 
					
						
							|  |  |  |  |      * @param inOffset   Index of in from which to start considering data.
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for encryption.
 | 
					
						
							|  |  |  |  |      * @return The ciphertext generated from a plaintext using the session key.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static byte[] blockEncrypt(byte[] in, int inOffset, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8
 | 
					
						
							|  |  |  |  |                         | (in[inOffset++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (in[inOffset] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         IP(L_R);
 | 
					
						
							|  |  |  |  |         encrypt(L_R, sessionKey);
 | 
					
						
							|  |  |  |  |         FP(L_R);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         return new byte[]{(byte) L, (byte) (L >> 8),
 | 
					
						
							|  |  |  |  |                 (byte) (L >> 16), (byte) (L >> 24), (byte) R, (byte) (R >> 8),
 | 
					
						
							|  |  |  |  |                 (byte) (R >> 16), (byte) (R >> 24)};
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Implements the Unix crypt(3) algorithm.
 | 
					
						
							|  |  |  |  |      * <p>
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param L0         Left 32 bits of a DES block.
 | 
					
						
							|  |  |  |  |      * @param R0         Right 32 bits of a DES block.
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for decryption.
 | 
					
						
							|  |  |  |  |      * @return The encrypted DES block.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static int[] crypt3(int L0, int R0, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] sKey = (int[]) sessionKey;
 | 
					
						
							|  |  |  |  |         int L = 0;
 | 
					
						
							|  |  |  |  |         int R = 0;
 | 
					
						
							|  |  |  |  |         int t, u, v;
 | 
					
						
							|  |  |  |  |         int n = sKey.length;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < 25; i++) {
 | 
					
						
							|  |  |  |  |             for (int j = 0; j < n; ) {
 | 
					
						
							|  |  |  |  |                 v = R ^ (R >>> 16);
 | 
					
						
							|  |  |  |  |                 u = v & L0;
 | 
					
						
							|  |  |  |  |                 v &= R0;
 | 
					
						
							|  |  |  |  |                 u ^= (u << 16) ^ R ^ sKey[j++];
 | 
					
						
							|  |  |  |  |                 t = v ^ (v << 16) ^ R ^ sKey[j++];
 | 
					
						
							|  |  |  |  |                 t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |                 L ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[u & 0x3F]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 v = L ^ (L >>> 16);
 | 
					
						
							|  |  |  |  |                 u = v & L0;
 | 
					
						
							|  |  |  |  |                 v &= R0;
 | 
					
						
							|  |  |  |  |                 u ^= (u << 16) ^ L ^ sKey[j++];
 | 
					
						
							|  |  |  |  |                 t = v ^ (v << 16) ^ L ^ sKey[j++];
 | 
					
						
							|  |  |  |  |                 t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |                 R ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[u & 0x3F]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                         | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             t = L;
 | 
					
						
							|  |  |  |  |             L = R;
 | 
					
						
							|  |  |  |  |             R = t;
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         int[] result = {R >>> 1 | R << 31, L >>> 1 | L << 31};
 | 
					
						
							|  |  |  |  |         FP(result);
 | 
					
						
							|  |  |  |  |         return result;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Decrypt exactly one block of ciphertext without applying IP nor FP.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io         The ciphertext (on input) and plaintext (on output) (as an
 | 
					
						
							|  |  |  |  |      *                   array of 8-bit entities).
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for decryption.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void decrypt(byte[] io, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (io[0] & 0xFF) | (io[1] & 0xFF) << 8 | (io[2] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[3] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (io[4] & 0xFF) | (io[5] & 0xFF) << 8 | (io[6] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[7] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         decrypt(L_R, sessionKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         io[0] = (byte) L;
 | 
					
						
							|  |  |  |  |         io[1] = (byte) (L >> 8);
 | 
					
						
							|  |  |  |  |         io[2] = (byte) (L >> 16);
 | 
					
						
							|  |  |  |  |         io[3] = (byte) (L >> 24);
 | 
					
						
							|  |  |  |  |         io[4] = (byte) R;
 | 
					
						
							|  |  |  |  |         io[5] = (byte) (R >> 8);
 | 
					
						
							|  |  |  |  |         io[6] = (byte) (R >> 16);
 | 
					
						
							|  |  |  |  |         io[7] = (byte) (R >> 24);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Decrypt in situ exactly one block of ciphertext without applying IP nor
 | 
					
						
							|  |  |  |  |      * FP.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io         The ciphertext (on input) and plaintext (on output) (as an
 | 
					
						
							|  |  |  |  |      *                   array of 32-bit entities).
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for decryption.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void decrypt(int[] io, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] sKey = (int[]) sessionKey;
 | 
					
						
							|  |  |  |  |         int L = io[0];
 | 
					
						
							|  |  |  |  |         int R = io[1];
 | 
					
						
							|  |  |  |  |         int u = R << 1 | R >>> 31;
 | 
					
						
							|  |  |  |  |         R = L << 1 | L >>> 31;
 | 
					
						
							|  |  |  |  |         L = u;
 | 
					
						
							|  |  |  |  |         int t;
 | 
					
						
							|  |  |  |  |         int n = sKey.length;
 | 
					
						
							|  |  |  |  |         for (int i = n - 1; i > 0; ) {
 | 
					
						
							|  |  |  |  |             t = R ^ sKey[i--];
 | 
					
						
							|  |  |  |  |             u = R ^ sKey[i--];
 | 
					
						
							|  |  |  |  |             t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |             L ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[u & 0x3F] | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             t = L ^ sKey[i--];
 | 
					
						
							|  |  |  |  |             u = L ^ sKey[i--];
 | 
					
						
							|  |  |  |  |             t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |             R ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[u & 0x3F] | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         io[0] = L >>> 1 | L << 31;
 | 
					
						
							|  |  |  |  |         io[1] = R >>> 1 | R << 31;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD>뷽<EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>(2001-07-04 14:29:13)
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     public void doit() {
 | 
					
						
							|  |  |  |  |         // boolean ok = false;
 | 
					
						
							|  |  |  |  |         int BLOCK_SIZE = 8;
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             byte[] kb = new byte[BLOCK_SIZE];
 | 
					
						
							|  |  |  |  |             byte[] pt = new byte[BLOCK_SIZE];
 | 
					
						
							|  |  |  |  |             int i;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for (i = 0; i < BLOCK_SIZE; i++)
 | 
					
						
							|  |  |  |  |                 kb[i] = (byte) i;
 | 
					
						
							|  |  |  |  |             for (i = 0; i < BLOCK_SIZE; i++)
 | 
					
						
							|  |  |  |  |                 pt[i] = (byte) i;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             Object key = makeKey(kb);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             byte[] ct = blockEncrypt(pt, 0, key);
 | 
					
						
							|  |  |  |  |             byte[] tmp = blockDecrypt(ct, 0, key);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             String[][] kat = {// KAT for a reduced set
 | 
					
						
							|  |  |  |  |                     // KEY, PLAINTEXT, CIPHERTEXT
 | 
					
						
							|  |  |  |  |                     {"0101010101010101", "95f8a5e5dd31d900",
 | 
					
						
							|  |  |  |  |                             "8000000000000000"},
 | 
					
						
							|  |  |  |  |                     {"0101010101010101", "dd7f121ca5015619",
 | 
					
						
							|  |  |  |  |                             "4000000000000000"},
 | 
					
						
							|  |  |  |  |                     {"0101010101010101", "2e8653104f3834ea",
 | 
					
						
							|  |  |  |  |                             "2000000000000000"},
 | 
					
						
							|  |  |  |  |                     // outer's data
 | 
					
						
							|  |  |  |  |                     {"0123456789abcdef", "0123456789abcde7",
 | 
					
						
							|  |  |  |  |                             "c95744256a5ed31d"},
 | 
					
						
							|  |  |  |  |                     {"0123456710325476", "89abcdef98badcfe",
 | 
					
						
							|  |  |  |  |                             "f0148eff050b2716"},};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for (i = 0; i < kat.length; ) {
 | 
					
						
							|  |  |  |  |                 key = makeKey(fromString(kat[i][0]));
 | 
					
						
							|  |  |  |  |                 pt = fromString(kat[i][1]);
 | 
					
						
							|  |  |  |  |                 ct = fromString(kat[i][2]);
 | 
					
						
							|  |  |  |  |                 i++;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 tmp = blockEncrypt(pt, 0, key);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 tmp = blockDecrypt(ct, 0, key);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // i do it
 | 
					
						
							|  |  |  |  |             key = makeKey(fromString(kat[0][0]));
 | 
					
						
							|  |  |  |  |             String strSrc;
 | 
					
						
							|  |  |  |  |             // byte[] bytSrc;
 | 
					
						
							|  |  |  |  |             String strCpt;
 | 
					
						
							|  |  |  |  |             byte[] bytCpt;
 | 
					
						
							|  |  |  |  |             String strDes;
 | 
					
						
							|  |  |  |  |             // byte[] bytDes;
 | 
					
						
							|  |  |  |  |             strSrc = "a <EFBFBD>й<EFBFBD><EFBFBD>ش<EFBFBD><EFBFBD>ﲩ<EFBFBD>й<EFBFBD>";
 | 
					
						
							|  |  |  |  |             strCpt = "";
 | 
					
						
							|  |  |  |  |             strDes = "";
 | 
					
						
							|  |  |  |  |             int intSrc = strSrc.getBytes().length;
 | 
					
						
							|  |  |  |  |             int intTemp;
 | 
					
						
							|  |  |  |  |             if ((intSrc % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             int intBlock = (intSrc / 8) + intTemp;
 | 
					
						
							|  |  |  |  |             byte[] bytBlock = new byte[intBlock * 8];
 | 
					
						
							|  |  |  |  |             bytBlock = strSrc.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] oBlock = new byte[8];
 | 
					
						
							|  |  |  |  |             int intpt;
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 if ((iBlock < (intBlock - 1)) || (intSrc % 8 == 0))
 | 
					
						
							|  |  |  |  |                     intpt = 8;
 | 
					
						
							|  |  |  |  |                 else
 | 
					
						
							|  |  |  |  |                     intpt = intSrc % 8;
 | 
					
						
							|  |  |  |  |                 if (intpt < 8) {
 | 
					
						
							|  |  |  |  |                     for (int ipt = 0; ipt < 8; ipt++)
 | 
					
						
							|  |  |  |  |                         oBlock[ipt] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytBlock, iBlock * 8, oBlock, 0, intpt);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 bytCpt = blockEncrypt(oBlock, 0, key);
 | 
					
						
							|  |  |  |  |                 strCpt = strCpt + toString(bytCpt);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             intSrc = strCpt.length();
 | 
					
						
							|  |  |  |  |             intBlock = (intSrc / 16);
 | 
					
						
							|  |  |  |  |             bytBlock = new byte[intSrc / 2];
 | 
					
						
							|  |  |  |  |             String[] strBlockc = new String[intBlock];
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 strBlockc[iBlock] = strCpt.substring(iBlock * 16,
 | 
					
						
							|  |  |  |  |                         iBlock * 16 + 16);
 | 
					
						
							|  |  |  |  |                 ct = fromString(strBlockc[iBlock]);
 | 
					
						
							|  |  |  |  |                 tmp = blockDecrypt(ct, 0, key);
 | 
					
						
							|  |  |  |  |                 System.arraycopy(tmp, 0, bytBlock, iBlock * 8, 8);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             strDes = new String(bytBlock);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             e.printStackTrace();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Encrypt in situ exactly one block of plaintext without applying IP nor
 | 
					
						
							|  |  |  |  |      * FP.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io         The plaintext (on input) and ciphertext (on output) (as an
 | 
					
						
							|  |  |  |  |      *                   array of 8-bit entities).
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for encryption.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void encrypt(byte[] io, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (io[0] & 0xFF) | (io[1] & 0xFF) << 8 | (io[2] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[3] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (io[4] & 0xFF) | (io[5] & 0xFF) << 8 | (io[6] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[7] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         encrypt(L_R, sessionKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         io[0] = (byte) L;
 | 
					
						
							|  |  |  |  |         io[1] = (byte) (L >> 8);
 | 
					
						
							|  |  |  |  |         io[2] = (byte) (L >> 16);
 | 
					
						
							|  |  |  |  |         io[3] = (byte) (L >> 24);
 | 
					
						
							|  |  |  |  |         io[4] = (byte) R;
 | 
					
						
							|  |  |  |  |         io[5] = (byte) (R >> 8);
 | 
					
						
							|  |  |  |  |         io[6] = (byte) (R >> 16);
 | 
					
						
							|  |  |  |  |         io[7] = (byte) (R >> 24);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Encrypt exactly one block of plaintext without applying IP nor FP.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io         The plaintext (on input) and ciphertext (on output) (as an
 | 
					
						
							|  |  |  |  |      *                   array of 32-bit entities).
 | 
					
						
							|  |  |  |  |      * @param sessionKey The session key to use for encryption.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void encrypt(int[] io, Object sessionKey) {
 | 
					
						
							|  |  |  |  |         int[] sKey = (int[]) sessionKey;
 | 
					
						
							|  |  |  |  |         int L = io[0];
 | 
					
						
							|  |  |  |  |         int R = io[1];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int u = R << 1 | R >>> 31;
 | 
					
						
							|  |  |  |  |         R = L << 1 | L >>> 31;
 | 
					
						
							|  |  |  |  |         L = u;
 | 
					
						
							|  |  |  |  |         int t;
 | 
					
						
							|  |  |  |  |         int n = sKey.length;
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < n; ) {
 | 
					
						
							|  |  |  |  |             u = R ^ sKey[i++];
 | 
					
						
							|  |  |  |  |             t = R ^ sKey[i++];
 | 
					
						
							|  |  |  |  |             t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |             L ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[u & 0x3F] | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             u = L ^ sKey[i++];
 | 
					
						
							|  |  |  |  |             t = L ^ sKey[i++];
 | 
					
						
							|  |  |  |  |             t = t >>> 4 | t << 28;
 | 
					
						
							|  |  |  |  |             R ^= (SP_TRANS[0x040 | (t & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x0C0 | ((t >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x140 | ((t >>> 16) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x1C0 | ((t >>> 24) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[u & 0x3F] | SP_TRANS[0x080 | ((u >>> 8) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SP_TRANS[0x100 | ((u >>> 16) & 0x3F)] | SP_TRANS[0x180 | ((u >>> 24) & 0x3F)]);
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         io[0] = L >>> 1 | L << 31;
 | 
					
						
							|  |  |  |  |         io[1] = R >>> 1 | R << 31;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // own methods
 | 
					
						
							|  |  |  |  |     // ...........................................................................
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * @return the length in bytes of an input block for this cipher.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static int engineBlockSize() {
 | 
					
						
							|  |  |  |  |         return BLOCK_SIZE;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Apply in situ the DES FP trnasformation (IP <sup>-1 </sup>) to a DES
 | 
					
						
							|  |  |  |  |      * block.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io DES block as an array of 32-bit entities.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void FP(byte[] io) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (io[0] & 0xFF) | (io[1] & 0xFF) << 8 | (io[2] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[3] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (io[4] & 0xFF) | (io[5] & 0xFF) << 8 | (io[6] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[7] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  |         FP(L_R);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         io[0] = (byte) L;
 | 
					
						
							|  |  |  |  |         io[1] = (byte) (L >> 8);
 | 
					
						
							|  |  |  |  |         io[2] = (byte) (L >> 16);
 | 
					
						
							|  |  |  |  |         io[3] = (byte) (L >> 24);
 | 
					
						
							|  |  |  |  |         io[4] = (byte) R;
 | 
					
						
							|  |  |  |  |         io[5] = (byte) (R >> 8);
 | 
					
						
							|  |  |  |  |         io[6] = (byte) (R >> 16);
 | 
					
						
							|  |  |  |  |         io[7] = (byte) (R >> 24);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Apply in situ the DES FP trnasformation (IP <sup>-1 </sup>) to a DES
 | 
					
						
							|  |  |  |  |      * block.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io DES block as an array of 32-bit entities.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void FP(int[] io) {
 | 
					
						
							|  |  |  |  |         int L = io[0];
 | 
					
						
							|  |  |  |  |         int R = io[1];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int t = (R >>> 1 ^ L) & 0x55555555;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 1;
 | 
					
						
							|  |  |  |  |         t = (L >>> 8 ^ R) & 0x00FF00FF;
 | 
					
						
							|  |  |  |  |         R ^= t;
 | 
					
						
							|  |  |  |  |         L ^= t << 8;
 | 
					
						
							|  |  |  |  |         t = (R >>> 2 ^ L) & 0x33333333;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 2;
 | 
					
						
							|  |  |  |  |         t = (L >>> 16 ^ R) & 0x0000FFFF;
 | 
					
						
							|  |  |  |  |         R ^= t;
 | 
					
						
							|  |  |  |  |         L ^= t << 16;
 | 
					
						
							|  |  |  |  |         t = (R >>> 4 ^ L) & 0x0F0F0F0F;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         io[0] = L ^ t;
 | 
					
						
							|  |  |  |  |         io[1] = R ^ (t << 4);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Returns a number from 0 to 15 corresponding to the hex digit <i>ch </i>.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static int fromDigit(char ch) {
 | 
					
						
							|  |  |  |  |         if (ch >= '0' && ch <= '9')
 | 
					
						
							|  |  |  |  |             return ch - '0';
 | 
					
						
							|  |  |  |  |         if (ch >= 'A' && ch <= 'F')
 | 
					
						
							|  |  |  |  |             return ch - 'A' + 10;
 | 
					
						
							|  |  |  |  |         if (ch >= 'a' && ch <= 'f')
 | 
					
						
							|  |  |  |  |             return ch - 'a' + 10;
 | 
					
						
							|  |  |  |  |         throw new IllegalArgumentException("Invalid hex digit '" + ch + "'");
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Returns a byte array from a string of hexadecimal digits.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static byte[] fromString(String hex) {
 | 
					
						
							|  |  |  |  |         int len = hex.length();
 | 
					
						
							|  |  |  |  |         byte[] buf = new byte[((len + 1) / 2)];
 | 
					
						
							|  |  |  |  |         int i = 0, j = 0;
 | 
					
						
							|  |  |  |  |         if ((len % 2) == 1)
 | 
					
						
							|  |  |  |  |             buf[j++] = (byte) fromDigit(hex.charAt(i++));
 | 
					
						
							|  |  |  |  |         while (i < len) {
 | 
					
						
							|  |  |  |  |             buf[j++] = (byte) ((fromDigit(hex.charAt(i++)) << 4) | fromDigit(hex
 | 
					
						
							|  |  |  |  |                     .charAt(i++)));
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return buf;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Returns a byte array from a string of hexadecimal digits.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static char[] fromString1(String hex) {
 | 
					
						
							|  |  |  |  |         int len = hex.length();
 | 
					
						
							|  |  |  |  |         char[] buf = new char[((len + 1) / 2)];
 | 
					
						
							|  |  |  |  |         int i = 0, j = 0;
 | 
					
						
							|  |  |  |  |         if ((len % 2) == 1)
 | 
					
						
							|  |  |  |  |             buf[j++] = (char) fromDigit(hex.charAt(i++));
 | 
					
						
							|  |  |  |  |         while (i < len) {
 | 
					
						
							|  |  |  |  |             buf[j++] = (char) ((fromDigit(hex.charAt(i++)) << 4) | fromDigit(hex
 | 
					
						
							|  |  |  |  |                     .charAt(i++)));
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return buf;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Apply in situ the DES IP trnasformation to a DES block.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io DES block as an array of 8-bit entities.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void IP(byte[] io) {
 | 
					
						
							|  |  |  |  |         int[] L_R = {
 | 
					
						
							|  |  |  |  |                 (io[0] & 0xFF) | (io[1] & 0xFF) << 8 | (io[2] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[3] & 0xFF) << 24,
 | 
					
						
							|  |  |  |  |                 (io[4] & 0xFF) | (io[5] & 0xFF) << 8 | (io[6] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                         | (io[7] & 0xFF) << 24};
 | 
					
						
							|  |  |  |  |         IP(L_R);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int L = L_R[0];
 | 
					
						
							|  |  |  |  |         int R = L_R[1];
 | 
					
						
							|  |  |  |  |         io[0] = (byte) L;
 | 
					
						
							|  |  |  |  |         io[1] = (byte) (L >> 8);
 | 
					
						
							|  |  |  |  |         io[2] = (byte) (L >> 16);
 | 
					
						
							|  |  |  |  |         io[3] = (byte) (L >> 24);
 | 
					
						
							|  |  |  |  |         io[4] = (byte) R;
 | 
					
						
							|  |  |  |  |         io[5] = (byte) (R >> 8);
 | 
					
						
							|  |  |  |  |         io[6] = (byte) (R >> 16);
 | 
					
						
							|  |  |  |  |         io[7] = (byte) (R >> 24);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Apply in situ the DES IP trnasformation to a DES block.
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param io DES block as an array of 32-bit entities.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static void IP(int[] io) {
 | 
					
						
							|  |  |  |  |         int L = io[0];
 | 
					
						
							|  |  |  |  |         int R = io[1];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int t = ((R >>> 4) ^ L) & 0x0F0F0F0F;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 4;
 | 
					
						
							|  |  |  |  |         t = ((L >>> 16) ^ R) & 0x0000FFFF;
 | 
					
						
							|  |  |  |  |         R ^= t;
 | 
					
						
							|  |  |  |  |         L ^= t << 16;
 | 
					
						
							|  |  |  |  |         t = ((R >>> 2) ^ L) & 0x33333333;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 2;
 | 
					
						
							|  |  |  |  |         t = ((L >>> 8) ^ R) & 0x00FF00FF;
 | 
					
						
							|  |  |  |  |         R ^= t;
 | 
					
						
							|  |  |  |  |         L ^= t << 8;
 | 
					
						
							|  |  |  |  |         t = ((R >>> 1) ^ L) & 0x55555555;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         io[0] = L ^ t;
 | 
					
						
							|  |  |  |  |         io[1] = R ^ (t << 1);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     protected static synchronized Object makeKey(byte[] k) {
 | 
					
						
							|  |  |  |  |         int i = 0;
 | 
					
						
							|  |  |  |  |         int L = (k[i++] & 0xFF) | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                 | (k[i++] & 0xFF) << 24;
 | 
					
						
							|  |  |  |  |         int R = (k[i++] & 0xFF) | (k[i++] & 0xFF) << 8 | (k[i++] & 0xFF) << 16
 | 
					
						
							|  |  |  |  |                 | (k[i++] & 0xFF) << 24;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int t = ((R >>> 4) ^ L) & 0x0F0F0F0F;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 4;
 | 
					
						
							|  |  |  |  |         t = ((L << 18) ^ L) & 0xCCCC0000;
 | 
					
						
							|  |  |  |  |         L ^= t ^ t >>> 18;
 | 
					
						
							|  |  |  |  |         t = ((R << 18) ^ R) & 0xCCCC0000;
 | 
					
						
							|  |  |  |  |         R ^= t ^ t >>> 18;
 | 
					
						
							|  |  |  |  |         t = ((R >>> 1) ^ L) & 0x55555555;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 1;
 | 
					
						
							|  |  |  |  |         t = ((L >>> 8) ^ R) & 0x00FF00FF;
 | 
					
						
							|  |  |  |  |         R ^= t;
 | 
					
						
							|  |  |  |  |         L ^= t << 8;
 | 
					
						
							|  |  |  |  |         t = ((R >>> 1) ^ L) & 0x55555555;
 | 
					
						
							|  |  |  |  |         L ^= t;
 | 
					
						
							|  |  |  |  |         R ^= t << 1;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         R = (R & 0x000000FF) << 16 | (R & 0x0000FF00) | (R & 0x00FF0000) >>> 16
 | 
					
						
							|  |  |  |  |                 | (L & 0xF0000000) >>> 4;
 | 
					
						
							|  |  |  |  |         L &= 0x0FFFFFFF;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int s;
 | 
					
						
							|  |  |  |  |         int j = 0;
 | 
					
						
							|  |  |  |  |         int[] sKey = new int[ROUNDS * 2];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         for (i = 0; i < ROUNDS; i++) {
 | 
					
						
							|  |  |  |  |             if ((0x7EFC >> i & 1) == 1) {
 | 
					
						
							|  |  |  |  |                 L = (L >>> 2 | L << 26) & 0x0FFFFFFF;
 | 
					
						
							|  |  |  |  |                 R = (R >>> 2 | R << 26) & 0x0FFFFFFF;
 | 
					
						
							|  |  |  |  |             } else {
 | 
					
						
							|  |  |  |  |                 L = (L >>> 1 | L << 27) & 0x0FFFFFFF;
 | 
					
						
							|  |  |  |  |                 R = (R >>> 1 | R << 27) & 0x0FFFFFFF;
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |             s = SKB[L & 0x3F]
 | 
					
						
							|  |  |  |  |                     | SKB[0x040 | (((L >>> 6) & 0x03) | ((L >>> 7) & 0x3C))]
 | 
					
						
							|  |  |  |  |                     | SKB[0x080 | (((L >>> 13) & 0x0F) | ((L >>> 14) & 0x30))]
 | 
					
						
							|  |  |  |  |                     | SKB[0x0C0 | (((L >>> 20) & 0x01) | ((L >>> 21) & 0x06) | ((L >>> 22) & 0x38))];
 | 
					
						
							|  |  |  |  |             t = SKB[0x100 | (R & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SKB[0x140 | (((R >>> 7) & 0x03) | ((R >>> 8) & 0x3C))]
 | 
					
						
							|  |  |  |  |                     | SKB[0x180 | ((R >>> 15) & 0x3F)]
 | 
					
						
							|  |  |  |  |                     | SKB[0x1C0 | (((R >>> 21) & 0x0F) | ((R >>> 22) & 0x30))];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             sKey[j++] = t << 16 | (s & 0x0000FFFF);
 | 
					
						
							|  |  |  |  |             s = s >>> 16 | (t & 0xFFFF0000);
 | 
					
						
							|  |  |  |  |             sKey[j++] = s << 4 | s >>> 28;
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return sKey;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     protected String stringDec(String strCpt, String strKey) {
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         String strDes = "";
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             int intTemp;
 | 
					
						
							|  |  |  |  |             int intKey = strKey.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intKey % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             byte[] bytKeyAll = new byte[(intKey / 8 + intTemp) * 8];
 | 
					
						
							|  |  |  |  |             bytKeyAll = strKey.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] bytKey = new byte[8];
 | 
					
						
							|  |  |  |  |             if (intKey < 8) {
 | 
					
						
							|  |  |  |  |                 for (int iob = 0; iob < 8; iob++)
 | 
					
						
							|  |  |  |  |                     bytKey[iob] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, intKey);
 | 
					
						
							|  |  |  |  |             } else
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, 8);
 | 
					
						
							|  |  |  |  |             Object key = makeKey(bytKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             int intCpt = strCpt.length();
 | 
					
						
							|  |  |  |  |             int intBlock = (intCpt / 16);
 | 
					
						
							|  |  |  |  |             byte[] bytBlock = new byte[intCpt / 2];
 | 
					
						
							|  |  |  |  |             String[] strBlock = new String[intBlock];
 | 
					
						
							|  |  |  |  |             byte[] tmp = new byte[8];
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 strBlock[iBlock] = strCpt.substring(iBlock * 16,
 | 
					
						
							|  |  |  |  |                         iBlock * 16 + 16);
 | 
					
						
							|  |  |  |  |                 tmp = blockDecrypt(fromString(strBlock[iBlock]), 0, key);
 | 
					
						
							|  |  |  |  |                 System.arraycopy(tmp, 0, bytBlock, iBlock * 8, 8);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             strDes = new String(bytBlock);
 | 
					
						
							|  |  |  |  |             strDes = strDes.trim();
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             strDes = "error:" + e.getMessage();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return strDes;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * <EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param strCpt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      * @param strKey <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ
 | 
					
						
							|  |  |  |  |      * @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected char[] charDec(String strCpt, String strKey) {
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         byte[] bytBlock = null;
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             int intTemp;
 | 
					
						
							|  |  |  |  |             int intKey = strKey.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intKey % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             byte[] bytKeyAll = new byte[(intKey / 8 + intTemp) * 8];
 | 
					
						
							|  |  |  |  |             bytKeyAll = strKey.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] bytKey = new byte[8];
 | 
					
						
							|  |  |  |  |             if (intKey < 8) {
 | 
					
						
							|  |  |  |  |                 for (int iob = 0; iob < 8; iob++)
 | 
					
						
							|  |  |  |  |                     bytKey[iob] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, intKey);
 | 
					
						
							|  |  |  |  |             } else
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, 8);
 | 
					
						
							|  |  |  |  |             Object key = makeKey(bytKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             int intCpt = strCpt.length();
 | 
					
						
							|  |  |  |  |             int intBlock = (intCpt / 16);
 | 
					
						
							|  |  |  |  |             bytBlock = new byte[intCpt / 2];
 | 
					
						
							|  |  |  |  |             String[] strBlock = new String[intBlock];
 | 
					
						
							|  |  |  |  |             byte[] tmp = new byte[8];
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 strBlock[iBlock] = strCpt.substring(iBlock * 16,
 | 
					
						
							|  |  |  |  |                         iBlock * 16 + 16);
 | 
					
						
							|  |  |  |  |                 tmp = blockDecrypt(fromString(strBlock[iBlock]), 0, key);
 | 
					
						
							|  |  |  |  |                 System.arraycopy(tmp, 0, bytBlock, iBlock * 8, 8);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             e.printStackTrace();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         char[] chars = new char[bytBlock.length];
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < bytBlock.length; i++) {
 | 
					
						
							|  |  |  |  |             chars[i] = (char) bytBlock[i];
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return chars;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     protected String stringEnc(String strSrc, String strKey) {
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         String strCpt = "";
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             int intTemp;
 | 
					
						
							|  |  |  |  |             int intKey = strKey.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intKey % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             byte[] bytKeyAll = new byte[(intKey / 8 + intTemp) * 8];
 | 
					
						
							|  |  |  |  |             bytKeyAll = strKey.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] bytKey = new byte[8];
 | 
					
						
							|  |  |  |  |             if (intKey < 8) {
 | 
					
						
							|  |  |  |  |                 for (int iob = 0; iob < 8; iob++)
 | 
					
						
							|  |  |  |  |                     bytKey[iob] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, intKey);
 | 
					
						
							|  |  |  |  |             } else
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, 8);
 | 
					
						
							|  |  |  |  |             Object key = makeKey(bytKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             byte[] bytCpt;
 | 
					
						
							|  |  |  |  |             int intSrc = strSrc.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intSrc % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             int intBlock = (intSrc / 8) + intTemp;
 | 
					
						
							|  |  |  |  |             byte[] bytBlock = new byte[intBlock * 8];
 | 
					
						
							|  |  |  |  |             bytBlock = strSrc.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] oBlock = new byte[8];
 | 
					
						
							|  |  |  |  |             int intpt;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             byte[] srcByte = new byte[intBlock * 8];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 if ((iBlock < (intBlock - 1)) || (intSrc % 8 == 0))
 | 
					
						
							|  |  |  |  |                     intpt = 8;
 | 
					
						
							|  |  |  |  |                 else
 | 
					
						
							|  |  |  |  |                     intpt = intSrc % 8;
 | 
					
						
							|  |  |  |  |                 if (intpt < 8) {
 | 
					
						
							|  |  |  |  |                     for (int ipt = 0; ipt < 8; ipt++)
 | 
					
						
							|  |  |  |  |                         oBlock[ipt] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytBlock, iBlock * 8, oBlock, 0, intpt);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 bytCpt = blockEncrypt(oBlock, 0, key);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytCpt, 0, srcByte, iBlock * 8, bytCpt.length);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 strCpt = strCpt + toString(bytCpt);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             strCpt = "error:" + e.getMessage();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         return strCpt;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * <EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      *
 | 
					
						
							|  |  |  |  |      * @param strSrc <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      * @param strKey <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ
 | 
					
						
							|  |  |  |  |      * @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected char[] charEnc(String strSrc, String strKey) {
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         String strCpt = "";
 | 
					
						
							|  |  |  |  |         byte[] srcByte = null;
 | 
					
						
							|  |  |  |  |         try {
 | 
					
						
							|  |  |  |  |             int intTemp;
 | 
					
						
							|  |  |  |  |             int intKey = strKey.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intKey % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             byte[] bytKeyAll = new byte[(intKey / 8 + intTemp) * 8];
 | 
					
						
							|  |  |  |  |             bytKeyAll = strKey.getBytes();
 | 
					
						
							|  |  |  |  |             byte[] bytKey = new byte[8];
 | 
					
						
							|  |  |  |  |             if (intKey < 8) {
 | 
					
						
							|  |  |  |  |                 for (int iob = 0; iob < 8; iob++)
 | 
					
						
							|  |  |  |  |                     bytKey[iob] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, intKey);
 | 
					
						
							|  |  |  |  |             } else
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytKeyAll, 0, bytKey, 0, 8);
 | 
					
						
							|  |  |  |  |             Object key = makeKey(bytKey);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             byte[] bytCpt;
 | 
					
						
							|  |  |  |  |             int intSrc = strSrc.getBytes().length;
 | 
					
						
							|  |  |  |  |             if ((intSrc % 8) == 0)
 | 
					
						
							|  |  |  |  |                 intTemp = 0;
 | 
					
						
							|  |  |  |  |             else
 | 
					
						
							|  |  |  |  |                 intTemp = 1;
 | 
					
						
							|  |  |  |  |             int intBlock = (intSrc / 8) + intTemp;
 | 
					
						
							|  |  |  |  |             char[] bytBlock = new char[intBlock * 8];
 | 
					
						
							|  |  |  |  |             bytBlock = strSrc.toCharArray();
 | 
					
						
							|  |  |  |  |             byte[] oBlock = new byte[8];
 | 
					
						
							|  |  |  |  |             int intpt;
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             srcByte = new byte[intBlock * 8];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             for (int iBlock = 0; iBlock < intBlock; iBlock++) {
 | 
					
						
							|  |  |  |  |                 if ((iBlock < (intBlock - 1)) || (intSrc % 8 == 0))
 | 
					
						
							|  |  |  |  |                     intpt = 8;
 | 
					
						
							|  |  |  |  |                 else
 | 
					
						
							|  |  |  |  |                     intpt = intSrc % 8;
 | 
					
						
							|  |  |  |  |                 if (intpt < 8) {
 | 
					
						
							|  |  |  |  |                     for (int ipt = 0; ipt < 8; ipt++)
 | 
					
						
							|  |  |  |  |                         oBlock[ipt] = fromString("00")[0];
 | 
					
						
							|  |  |  |  |                 }
 | 
					
						
							|  |  |  |  |                 for (int iob = 0; iob < intpt; iob++)
 | 
					
						
							|  |  |  |  |                     oBlock[iob] = (byte) bytBlock[iBlock * 8 + iob];
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 bytCpt = blockEncrypt(oBlock, 0, key);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 System.arraycopy(bytCpt, 0, srcByte, iBlock * 8, bytCpt.length);
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                 System.out.println("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>" + toString(srcByte));
 | 
					
						
							|  |  |  |  |                 strCpt = strCpt + toString(bytCpt);
 | 
					
						
							|  |  |  |  |             }
 | 
					
						
							|  |  |  |  |         } catch (Exception e) {
 | 
					
						
							|  |  |  |  |             strCpt = "error:" + e.getMessage();
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         char[] srcChar = new char[srcByte.length];
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < srcByte.length; i++) {
 | 
					
						
							|  |  |  |  |             srcChar[i] = (char) srcByte[i];
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return srcChar;
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     /**
 | 
					
						
							|  |  |  |  |      * Returns a string of hexadecimal digits from a byte array. Each byte is
 | 
					
						
							|  |  |  |  |      * converted to 2 hex symbols.
 | 
					
						
							|  |  |  |  |      */
 | 
					
						
							|  |  |  |  |     protected static String toString(byte[] ba) {
 | 
					
						
							|  |  |  |  |         int length = ba.length;
 | 
					
						
							|  |  |  |  |         char[] buf = new char[length * 2];
 | 
					
						
							|  |  |  |  |         for (int i = 0, j = 0, k; i < length; ) {
 | 
					
						
							|  |  |  |  |             k = ba[i++];
 | 
					
						
							|  |  |  |  |             buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
 | 
					
						
							|  |  |  |  |             buf[j++] = HEX_DIGITS[k & 0x0F];
 | 
					
						
							|  |  |  |  |         }
 | 
					
						
							|  |  |  |  |         return new String(buf);
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public static void main(String[] args) {
 | 
					
						
							|  |  |  |  |         DesHelper desHelper = new DesHelper();
 | 
					
						
							|  |  |  |  |         char[] chars = new char[]{0x96, 0xD0, 0x02, 0x88, 0x78, 0xD5, 0x8C,
 | 
					
						
							|  |  |  |  |                 0x89};
 | 
					
						
							|  |  |  |  |         System.out.println("stringEnc:" + desHelper.stringEnc("232323", "2017ynxbdkj8891"));
 | 
					
						
							|  |  |  |  |     }
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | }
 |