3DES加密(C代碼java重寫)

package com.bocom.bbip.jxeups.interceptor.mob;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
/**
*3DES加密
*2015年8月31日 19:49:08
*/
public class MobDes {

/** WINDOWS操作系統 */
public String OS_WINDOWS = "Windows";

/** LINUX操作系統 */
public String os_LINUX = "LINUX";

/** 請根據不同的系統,設置不同的操作系統ID */
public String OS_NAME = "OTHER";

public boolean IsWinOrLix = (OS_WINDOWS.equals(OS_NAME) || os_LINUX
        .equals(OS_NAME));

/** BIT 設置 */
byte[] BIT = new byte[] { (byte) 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
        (byte) 0x80 };

private String DES_KEY = "yangpengit";

/**
 *   set x binary of ipr_abyte to y binary of ip1_abyte ,for
 * example:<br/>
 * &nbsp;&nbsp;bit order 01234567<br/>
 * <br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;ipr_abyte = 0x73(0111 0011)<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;ip1_abyte = 0x25(0010 0101)<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;changeBit(0x73, 7, 0x25, 0)<br/>
 * 
 * @param ipr_abyte
 * @param x
 * @param ip1_abyte
 * @param y
 * @return
 */
private byte changeBit(byte ipr_abyte, int x, byte ip1_abyte, int y) {
    if (IsWinOrLix) {
        if ((ip1_abyte & BIT[y]) != 0) {
            // x[5] 修改爲1 x[5] | 0000 0010 => x[5] | BIT[7-5]
            ipr_abyte |= BIT[x];
        } else {
            // x[5] 修改爲0 x[5] & 1111 1101 => x[5] & ~BIT[7-5]
            ipr_abyte &= ~BIT[x];
        }
    } else {
        if ((ip1_abyte & BIT[7 - y]) != 0) {
            // x[5] 修改爲1 x[5] | 0000 0010 => x[5] | BIT[7-5]
            ipr_abyte |= BIT[7 - x];
        } else {
            // x[5] 修改爲0 x[5] & 1111 1101 => x[5] & ~BIT[7-5]
            ipr_abyte &= ~BIT[7 - x];
        }
    }
    return ipr_abyte;
}

/**
 * 
 * @param bit
 * @param x
 * @return
 */
private byte setBIT_0(byte bit, int x) {
    if (IsWinOrLix) {
        return (byte) (bit & ~BIT[x]);
    } else {
        return (byte) (bit & ~BIT[7 - x]);
    }
}

private void expand(byte[] in, byte[] out) {
    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0); /* bit 32 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* bit 1 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /* bit 2 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5); /* bit 3 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4); /* bit 4 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /* bit 5 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /* bit 4 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3); /* bit 5 */
    out[5] = ipr_abyte;

    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* bit 6 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* bit 7 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* bit 8 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /* bit 9 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* bit 8 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7); /* bit 9 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /* bit 10 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5); /* bit 11 */
    out[4] = ipr_abyte;

    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* bit 12 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /* bit 13 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /* bit 12 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /* bit 13 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* bit 14 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1); /* bit 15 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0); /* bit 16 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* bit 17 */
    out[3] = ipr_abyte;

    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0); /* bit 16 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* bit 17 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /* bit 18 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5); /* bit 19 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4); /* bit 20 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /* bit 21 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /* bit 20 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3); /* bit 21 */
    out[2] = ipr_abyte;

    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* bit 22 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* bit 23 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* bit 24 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /* bit 25 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* bit 24 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7); /* bit 25 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /* bit 26 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5); /* bit 27 */
    out[1] = ipr_abyte;

    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* bit 28 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /* bit 29 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /* bit 28 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /* bit 29 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* bit 30 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1); /* bit 31 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0); /* bit 32 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* bit 1 */
    out[0] = ipr_abyte;

    return;
}

private void compress(byte[] in, byte[] out) {

    /* S Box [8][4][16] */
    byte[][][] s = new byte[][][] {
            { /* S1 */
                    { 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 } },
            {/* S2 */
                    { 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 } },
            {/* S3 */
                    { 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 } },
            {/* S4 */
                    { 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 } },
            {/* S5 */
                    { 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 } },
            {/* S6 */
                    { 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 } },
            {/* S7 */
                    { 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 } },
            {/* S8 */
                    { 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 } },

    };

    byte[] tmp = new byte[8];
    byte[] c = new byte[8];
    int i;

    byte hang, lie;
    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Trans 6 bytes to 8 bytes of 6 bits */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /* bit 1 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6); /* bit 2 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /* bit 3 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /* bit 4 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /* bit 5 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2); /* bit 6 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[7] = ipr_abyte;

    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* bit 7 */
    ip1_abyte = in[5];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* bit 8 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7); /* bit 9 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /* bit 10 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /* bit 11 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /* bit 12 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[6] = ipr_abyte;

    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* bit 13 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* bit 14 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* bit 15 */
    ip1_abyte = in[4];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0); /* bit 16 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /* bit 17 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /* bit 18 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[5] = ipr_abyte;

    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /* bit 19 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /* bit 20 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /* bit 21 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* bit 22 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* bit 23 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0); /* bit 24 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[4] = ipr_abyte;

    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /* bit 25 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6); /* bit 26 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /* bit 27 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /* bit 28 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /* bit 29 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2); /* bit 30 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[3] = ipr_abyte;

    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* bit 31 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* bit 32 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7); /* bit 33 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /* bit 34 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /* bit 35 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /* bit 36 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[2] = ipr_abyte;

    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* bit 37 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* bit 38 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* bit 39 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0); /* bit 40 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /* bit 41 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /* bit 42 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[1] = ipr_abyte;

    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /* bit 43 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /* bit 44 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /* bit 45 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* bit 46 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* bit 47 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0); /* bit 48 */
    ipr_abyte = setBIT_0(ipr_abyte, 1);
    ipr_abyte = setBIT_0(ipr_abyte, 0);
    tmp[0] = ipr_abyte;

    /* Compress 6 bits to 4 bits */
    i = 7;
    while (i >= 0) {
        ip1_abyte = tmp[i];
        ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7); /* Hang Number */
        ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2);
        hang = (byte) (ipr_abyte & 0x03);

        ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6); /* Lie Number */
        ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5);
        ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4);
        ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3);
        lie = (byte) (ipr_abyte & 0x0F);

        c[i] = s[7 - i][hang][lie];
        i = i - 1;
    }

    out[3] = (byte) ((c[7] << 4) | c[6]);
    out[2] = (byte) ((c[5] << 4) | c[4]);
    out[1] = (byte) ((c[3] << 4) | c[2]);
    out[0] = (byte) ((c[1] << 4) | c[0]);
}

private void permutate(byte[] in, byte[] out) {

    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Trans Array Out[4] */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0); /* bit 16 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* bit 7 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /* bit 20 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /* bit 21 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /* bit 29 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /* bit 12 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /* bit 28 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* bit 17 */
    out[3] = ipr_abyte;

    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /* bit 1 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* bit 15 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* bit 23 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /* bit 26 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /* bit 5 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /* bit 18 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1); /* bit 31 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6); /* bit 10 */
    out[2] = ipr_abyte;

    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6); /* bit 2 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* bit 8 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* bit 24 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* bit 14 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* bit 32 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /* bit 27 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /* bit 3 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* bit 9 */
    out[1] = ipr_abyte;

    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /* bit 19 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /* bit 13 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2); /* bit 30 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* bit 6 */
    ip1_abyte = in[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* bit 22 */
    ip1_abyte = in[2];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /* bit 11 */
    ip1_abyte = in[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /* bit 4 */
    ip1_abyte = in[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* bit 25 */
    out[0] = ipr_abyte;

    return;
}

private void pc2(byte[] keyc, byte[] keyd, byte[] subkey) {

    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Trans Ci */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* bit 14 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* bit 17 */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /* bit 11 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0); /* bit 24 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /* bit 1 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /* bit 5 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /* bit 3 */
    ip1_abyte = keyc[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* bit 28 */
    subkey[5] = ipr_abyte;

    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* bit 15 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* bit 6 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /* bit 21 */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /* bit 10 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* bit 23 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /* bit 19 */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /* bit 12 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* bit 4 */
    subkey[4] = ipr_abyte;

    ip1_abyte = keyc[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6); /* bit 26 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* bit 8 */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* bit 16 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1); /* bit 7 */
    ip1_abyte = keyc[0];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /* bit 27 */
    ip1_abyte = keyc[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /* bit 20 */
    ip1_abyte = keyc[2];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3); /* bit 13 */
    ip1_abyte = keyc[3];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6); /* bit 2 */
    subkey[3] = ipr_abyte;

    /* Trans Di */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* bit 41 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* bit 52 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /* bit 31 */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /* bit 37 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /* bit 47 */
    ip1_abyte = keyd[0];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /* bit 55 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /* bit 30 */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* bit 40 */
    subkey[2] = ipr_abyte;

    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* bit 51 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* bit 45 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /* bit 33 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /* bit 48 */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* bit 44 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /* bit 49 */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /* bit 39 */
    ip1_abyte = keyd[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* bit 56 */
    subkey[1] = ipr_abyte;

    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* bit 34 */
    ip1_abyte = keyd[0];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* bit 53 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /* bit 46 */
    ip1_abyte = keyd[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* bit 42 */
    ip1_abyte = keyd[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* bit 50 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0); /* bit 36 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7); /* bit 29 */
    ip1_abyte = keyd[3];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* bit 32 */
    subkey[0] = ipr_abyte;

}

private void rotatebits(byte[] key, byte[] skey, byte bits) {
    byte[] c = new byte[4];
    byte[] d = new byte[4];

    c[0] = key[0];
    c[1] = key[1];
    c[2] = key[2];
    c[3] = key[3];

    /* total 28 bits */
    if (bits == 1) {
        /* Key[0] */
        d[0] = changeBit(d[0], 4, c[3], 7); /* bit 1 */

        d[0] = changeBit(d[0], 5, c[0], 4); /* bit 2 */
        d[0] = changeBit(d[0], 6, c[0], 5); /* bit 3 */
        d[0] = changeBit(d[0], 7, c[0], 6); /* bit 4 */

        /* key[1] */
        d[1] = changeBit(d[1], 0, c[0], 7); /* bit 5 */
        d[1] = changeBit(d[1], 1, c[1], 0); /* bit 6 */
        d[1] = changeBit(d[1], 2, c[1], 1); /* bit 7 */
        d[1] = changeBit(d[1], 3, c[1], 2); /* bit 8 */
        d[1] = changeBit(d[1], 4, c[1], 3); /* bit 9 */
        d[1] = changeBit(d[1], 5, c[1], 4); /* bit 10 */
        d[1] = changeBit(d[1], 6, c[1], 5); /* bit 11 */
        d[1] = changeBit(d[1], 7, c[1], 6); /* bit 12 */

        /* key[2] */
        d[2] = changeBit(d[2], 0, c[1], 7); /* bit 13 */
        d[2] = changeBit(d[2], 1, c[2], 0); /* bit 14 */
        d[2] = changeBit(d[2], 2, c[2], 1); /* bit 15 */
        d[2] = changeBit(d[2], 3, c[2], 2); /* bit 16 */
        d[2] = changeBit(d[2], 4, c[2], 3); /* bit 17 */
        d[2] = changeBit(d[2], 5, c[2], 4); /* bit 18 */
        d[2] = changeBit(d[2], 6, c[2], 5); /* bit 19 */
        d[2] = changeBit(d[2], 7, c[2], 6); /* bit 20 */

        /* key[3] */
        d[3] = changeBit(d[3], 0, c[2], 7); /* bit 21 */
        d[3] = changeBit(d[3], 1, c[3], 0); /* bit 22 */
        d[3] = changeBit(d[3], 2, c[3], 1); /* bit 23 */
        d[3] = changeBit(d[3], 3, c[3], 2); /* bit 24 */
        d[3] = changeBit(d[3], 4, c[3], 3); /* bit 25 */
        d[3] = changeBit(d[3], 5, c[3], 4); /* bit 26 */
        d[3] = changeBit(d[3], 6, c[3], 5); /* bit 27 */
        d[3] = changeBit(d[3], 7, c[3], 6); /* bit 28 */
    } else { /* Left rotate 2 bits */
        /* Key[0] */
        d[0] = changeBit(d[0], 4, c[3], 6); /* bit 1 */
        d[0] = changeBit(d[0], 5, c[3], 7); /* bit 2 */

        d[0] = changeBit(d[0], 6, c[0], 4); /* bit 3 */
        d[0] = changeBit(d[0], 7, c[0], 5); /* bit 4 */

        /* key[1] */
        d[1] = changeBit(d[1], 0, c[0], 6); /* bit 5 */
        d[1] = changeBit(d[1], 1, c[0], 7); /* bit 6 */
        d[1] = changeBit(d[1], 2, c[1], 0); /* bit 7 */
        d[1] = changeBit(d[1], 3, c[1], 1); /* bit 8 */
        d[1] = changeBit(d[1], 4, c[1], 2); /* bit 9 */
        d[1] = changeBit(d[1], 5, c[1], 3); /* bit 10 */
        d[1] = changeBit(d[1], 6, c[1], 4); /* bit 11 */
        d[1] = changeBit(d[1], 7, c[1], 5); /* bit 12 */

        /* key[2] */
        d[2] = changeBit(d[2], 0, c[1], 6); /* bit 13 */
        d[2] = changeBit(d[2], 1, c[1], 7); /* bit 14 */
        d[2] = changeBit(d[2], 2, c[2], 0); /* bit 15 */
        d[2] = changeBit(d[2], 3, c[2], 1); /* bit 16 */
        d[2] = changeBit(d[2], 4, c[2], 2); /* bit 17 */
        d[2] = changeBit(d[2], 5, c[2], 3); /* bit 18 */
        d[2] = changeBit(d[2], 6, c[2], 4); /* bit 19 */
        d[2] = changeBit(d[2], 7, c[2], 5); /* bit 20 */

        /* key[3] */
        d[3] = changeBit(d[3], 0, c[2], 6); /* bit 21 */
        d[3] = changeBit(d[3], 1, c[2], 7); /* bit 22 */
        d[3] = changeBit(d[3], 2, c[3], 0); /* bit 23 */
        d[3] = changeBit(d[3], 3, c[3], 1); /* bit 24 */
        d[3] = changeBit(d[3], 4, c[3], 2); /* bit 25 */
        d[3] = changeBit(d[3], 5, c[3], 3); /* bit 26 */
        d[3] = changeBit(d[3], 6, c[3], 4); /* bit 27 */
        d[3] = changeBit(d[3], 7, c[3], 5); /* bit 28 */
    }

    skey[0] = d[0];
    skey[1] = d[1];
    skey[2] = d[2];
    skey[3] = d[3];
    return;
}

private void Gsubkey(byte[] key, byte[][] subkey) {
    int i;
    byte[] cup = new byte[4], dup = new byte[4];
    byte[] ci = new byte[4], di = new byte[4];
    byte[] lsi = new byte[16];

    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Initial LSi */
    lsi[0] = lsi[1] = lsi[8] = lsi[15] = 1;
    lsi[2] = lsi[3] = lsi[4] = lsi[5] = lsi[6] = lsi[7] = 2;
    lsi[9] = lsi[10] = lsi[11] = lsi[12] = lsi[13] = lsi[14] = 2;

    /* Getout 1 bit of 1 des_byte: all 56 bytes */
    /* Through PC-1, Get C0, 28 bits */
    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /* 57 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /* 49 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7); /* 41 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /* 33 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /* 25 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7); /* 17 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7); /* 9 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /* 1 bit */
    ci[3] = ipr_abyte;

    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6); /* 58 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6); /* 50 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /* 42 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /* 34 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6); /* 26 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /* 18 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /* 10 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6); /* 2 bit */
    ci[2] = ipr_abyte;

    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /* 59 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 5); /* 51 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /* 43 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5); /* 35 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /* 27 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /* 19 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /* 11 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5); /* 3 bit */
    ci[1] = ipr_abyte;

    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* 60 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /* 52 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /* 44 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /* 36 bit */
    ci[0] = ipr_abyte;

    /* Through PC-1, Get D0, 28 its */
    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* 63 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* 55 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* 47 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1); /* 39 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* 31 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1); /* 23 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1); /* 15 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 1); /* 7 bit */
    di[3] = ipr_abyte;

    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* 62 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* 54 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2); /* 46 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* 38 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* 30 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2); /* 22 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 2); /* 14 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2); /* 6 bit */
    di[2] = ipr_abyte;

    ip1_abyte = key[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* 61 bit */
    ip1_abyte = key[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /* 53 bit */
    ip1_abyte = key[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /* 45 bit */
    ip1_abyte = key[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /* 37 bit */
    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /* 29 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /* 21 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3); /* 13 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3); /* 5 bit */
    di[1] = ipr_abyte;

    ip1_abyte = key[4];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* 28 bit */
    ip1_abyte = key[5];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /* 20 bit */
    ip1_abyte = key[6];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /* 12 bit */
    ip1_abyte = key[7];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /* 4 bit */
    di[0] = ipr_abyte;

    // printHex(ci, 0, 4);
    // printHex(di, 0, 4);

    for (i = 0; i < 16; i++) {
        cup[3] = ci[3];
        cup[2] = ci[2];
        cup[1] = ci[1];
        cup[0] = ci[0];

        dup[3] = di[3];
        dup[2] = di[2];
        dup[1] = di[1];
        dup[0] = di[0];

        // System.out.printf("i=%4d\n", i);

        // printHex(cup, 0, 4);
        /* Generate 16 Subkey */
        rotatebits(cup, ci, lsi[i]);
        // printHex(ci, 0, 4);

        // printHex(dup, 0, 4);
        rotatebits(dup, di, lsi[i]);
        // printHex(di, 0, 4);

        // System.out.println();

        pc2(ci, di, subkey[i]);
    }
}

/*-----------------------------------------------------------
  DES Main procedure
  Description: 
-----------------------------------------------------------*/
private void des(byte m[], byte key[]) {
    byte[] ip = new byte[8];
    byte[] lin = new byte[4];
    byte[] rin = new byte[4];
    byte[] lup = new byte[4];
    byte[] rup = new byte[4];
    byte[] tmp = new byte[6];
    byte[] tmp4 = new byte[4];
    byte[][] subkey = new byte[16][6];
    int i, j;

    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Subkey Generate */
    Gsubkey(key, subkey);

    /* IP trans */
    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6);
    ip[7] = ipr_abyte; /* byte7: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4);
    ip[6] = ipr_abyte; /* byte6: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 2);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2);
    ip[5] = ipr_abyte; /* byte5: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 0);
    ip[4] = ipr_abyte; /* byte4: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7);
    ip[3] = ipr_abyte; /* byte3: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 5);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5);
    ip[2] = ipr_abyte; /* byte2: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3);
    ip[1] = ipr_abyte; /* byte1: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 1);
    ip[0] = ipr_abyte; /* byte0: 8 bits */

    /* Generate L0, R0 */
    lin[3] = ip[7];
    lin[2] = ip[6];
    lin[1] = ip[5];
    lin[0] = ip[4]; /* L0 */
    rin[3] = ip[3];
    rin[2] = ip[2];
    rin[1] = ip[1];
    rin[0] = ip[0]; /* R0 */

    /* Generate Ri, Li (16 Times) */
    for (j = 0; j < 16; j = j + 1) {

        for (i = 0; i < 4; i = i + 1) {
            lup[i] = lin[i];
        }
        for (i = 0; i < 4; i = i + 1) {
            rup[i] = rin[i];
        }
        /* Expand Operation */
        expand(rup, tmp);
        /* 48 bits MOD 2 */
        for (i = 0; i < 6; i = i + 1) {
            tmp[i] = (byte) (tmp[i] ^ subkey[j][i]);
        }
        /* Compress Operation */
        compress(tmp, rin);
        /* Permutation */
        permutate(rin, tmp4);
        /* 32 bits MOD 2 */
        for (i = 0; i < 4; i = i + 1) {
            rin[i] = (byte) (lup[i] ^ tmp4[i]);
        } /* Ri */
        for (i = 0; i < 4; i = i + 1) {
            lin[i] = rup[i];
        } /* Li */

    }
    /* Generate R16, L16 */
    for (i = 0; i < 4; i = i + 1) {
        tmp4[i] = rin[i];
    }
    for (i = 0; i < 4; i = i + 1) {
        rin[i] = lin[i];
    }
    for (i = 0; i < 4; i = i + 1) {
        lin[i] = tmp4[i];
    }

    /* IP(-1) trans */
    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0); /* 40 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* 8 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* 48 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0); /* 16 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* 56 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0); /* 24 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0); /* 64 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 0); /* 32 */
    ip[7] = ipr_abyte; /* byte7: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* 39 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* 7 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* 47 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1); /* 15 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* 55 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1); /* 23 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1); /* 63 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 1); /* 31 */
    ip[6] = ipr_abyte; /* byte6: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* 38 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* 6 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2); /* 46 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* 14 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* 54 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2); /* 22 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 2); /* 62 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2); /* 30 */
    ip[5] = ipr_abyte; /* byte5: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* 37 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3); /* 29 */
    ip[4] = ipr_abyte; /* byte4: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* 36 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* 28 */
    ip[3] = ipr_abyte; /* byte3: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /*  */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 5); /*  */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /*  */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5); /*  */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /*  */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /*  */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /*  */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5); /*  */
    ip[2] = ipr_abyte; /* byte2: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6); /*  */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6); /*  */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /*  */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /*  */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6); /*  */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /*  */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /*  */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6); /*  */
    ip[1] = ipr_abyte; /* byte1: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /*  */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /*  */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7); /*  */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /*  */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /*  */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7); /*  */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7); /*  */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /*  */
    ip[0] = ipr_abyte; /* byte0: 8 bits */

    m[7] = ip[7];
    m[6] = ip[6];
    m[5] = ip[5];
    m[4] = ip[4];
    m[3] = ip[3];
    m[2] = ip[2];
    m[1] = ip[1];
    m[0] = ip[0];
    return;
}

/*-----------------------------------------------------------
  UN-DES Main procedure
  Description: 
-----------------------------------------------------------*/
private void undes(byte m[], byte key[]) {
    byte[] ip = new byte[8];
    byte[] lin = new byte[4];
    byte[] rin = new byte[4];
    byte[] lup = new byte[4];
    byte[] rup = new byte[4];
    byte[] tmp = new byte[6];
    byte[] tmp4 = new byte[4];
    byte[][] subkey = new byte[16][6];
    int i, j;

    byte ip1_abyte = 0;
    byte ipr_abyte = 0;

    /* Subkey Generate */
    Gsubkey(key, subkey);

    /* IP trans */
    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6);
    ip[7] = ipr_abyte; /* byte7: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4);
    ip[6] = ipr_abyte; /* byte6: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 2);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2);
    ip[5] = ipr_abyte; /* byte5: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 0);
    ip[4] = ipr_abyte; /* byte4: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7);
    ip[3] = ipr_abyte; /* byte3: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 5);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5);
    ip[2] = ipr_abyte; /* byte2: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3);
    ip[1] = ipr_abyte; /* byte1: 8 bits */

    ip1_abyte = m[0];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1);
    ip1_abyte = m[1];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1);
    ip1_abyte = m[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1);
    ip1_abyte = m[3];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1);
    ip1_abyte = m[4];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1);
    ip1_abyte = m[5];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1);
    ip1_abyte = m[6];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1);
    ip1_abyte = m[7];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 1);
    ip[0] = ipr_abyte; /* byte0: 8 bits */

    /* Generate L0, R0 */
    lin[3] = ip[7];
    lin[2] = ip[6];
    lin[1] = ip[5];
    lin[0] = ip[4]; /* L0 */
    rin[3] = ip[3];
    rin[2] = ip[2];
    rin[1] = ip[1];
    rin[0] = ip[0]; /* R0 */

    /* Generate Ri, Li (16 Times) */
    for (j = 0; j < 16; j = j + 1) {

        for (i = 0; i < 4; i = i + 1) {
            lup[i] = lin[i];
        }
        for (i = 0; i < 4; i = i + 1) {
            rup[i] = rin[i];
        }
        /* Expand Operation */
        expand(rup, tmp);
        /* 48 bits MOD 2 */
        for (i = 0; i < 6; i = i + 1) {
            tmp[i] = (byte) (tmp[i] ^ subkey[15 - j][i]);
        }
        /* Compress Operation */
        compress(tmp, rin);
        /* Permutation */
        permutate(rin, tmp4);
        /* 32 bits MOD 2 */
        for (i = 0; i < 4; i = i + 1) {
            rin[i] = (byte) (lup[i] ^ tmp4[i]);
        } /* Ri */
        for (i = 0; i < 4; i = i + 1) {
            lin[i] = rup[i];
        } /* Li */

    }
    /* Generate R16, L16 */
    for (i = 0; i < 4; i = i + 1) {
        tmp4[i] = rin[i];
    }
    for (i = 0; i < 4; i = i + 1) {
        rin[i] = lin[i];
    }
    for (i = 0; i < 4; i = i + 1) {
        lin[i] = tmp4[i];
    }

    /* IP(-1) trans */
    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 0); /* 40 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 0); /* 8 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 0); /* 48 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 0); /* 16 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 0); /* 56 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 0); /* 24 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 0); /* 64 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 0); /* 32 */
    ip[7] = ipr_abyte; /* byte7: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 1); /* 39 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 1); /* 7 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 1); /* 47 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 1); /* 15 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 1); /* 55 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 1); /* 23 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 1); /* 63 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 1); /* 31 */
    ip[6] = ipr_abyte; /* byte6: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 2); /* 38 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 2); /* 6 */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 2); /* 46 */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 2); /* 14 */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 2); /* 54 */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 2); /* 22 */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 2); /* 62 */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 2); /* 30 */
    ip[5] = ipr_abyte; /* byte5: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 3); /* 37 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 3); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 3); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 3); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 3); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 3); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 3); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 3); /* 29 */
    ip[4] = ipr_abyte; /* byte4: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 4); /* 36 */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 4); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 4); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 4); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 4); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 4); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 4); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 4); /* 28 */
    ip[3] = ipr_abyte; /* byte3: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 5); /*    */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 5); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 5); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 5); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 5); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 5); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 5); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 5); /*    */
    ip[2] = ipr_abyte; /* byte2: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 6); /*    */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 6); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 6); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 6); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 6); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 6); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 6); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 6); /*    */
    ip[1] = ipr_abyte; /* byte1: 8 bits */

    ip1_abyte = rin[3];
    ipr_abyte = changeBit(ipr_abyte, 7, ip1_abyte, 7); /*    */
    ip1_abyte = lin[3];
    ipr_abyte = changeBit(ipr_abyte, 6, ip1_abyte, 7); /*    */
    ip1_abyte = rin[2];
    ipr_abyte = changeBit(ipr_abyte, 5, ip1_abyte, 7); /*    */
    ip1_abyte = lin[2];
    ipr_abyte = changeBit(ipr_abyte, 4, ip1_abyte, 7); /*    */
    ip1_abyte = rin[1];
    ipr_abyte = changeBit(ipr_abyte, 3, ip1_abyte, 7); /*    */
    ip1_abyte = lin[1];
    ipr_abyte = changeBit(ipr_abyte, 2, ip1_abyte, 7); /*    */
    ip1_abyte = rin[0];
    ipr_abyte = changeBit(ipr_abyte, 1, ip1_abyte, 7); /*    */
    ip1_abyte = lin[0];
    ipr_abyte = changeBit(ipr_abyte, 0, ip1_abyte, 7); /*    */
    ip[0] = ipr_abyte; /* byte0: 8 bits */

    m[7] = ip[7];
    m[6] = ip[6];
    m[5] = ip[5];
    m[4] = ip[4];
    m[3] = ip[3];
    m[2] = ip[2];
    m[1] = ip[1];
    m[0] = ip[0];
    return;
}

private void SDes(byte orientation, byte[] PlainText, byte[] Key,
        byte[] Encipher) {
    byte[] m = new byte[8];
    byte[] k = new byte[8];

    m[0] = PlainText[7];
    m[1] = PlainText[6];
    m[2] = PlainText[5];
    m[3] = PlainText[4];
    m[4] = PlainText[3];
    m[5] = PlainText[2];
    m[6] = PlainText[1];
    m[7] = PlainText[0];

    k[0] = Key[7];
    k[1] = Key[6];
    k[2] = Key[5];
    k[3] = Key[4];
    k[4] = Key[3];
    k[5] = Key[2];
    k[6] = Key[1];
    k[7] = Key[0];

    if (orientation == 0) {
        des(m, k);
    } else {
        undes(m, k);
    }

    Encipher[0] = m[7];
    Encipher[1] = m[6];
    Encipher[2] = m[5];
    Encipher[3] = m[4];
    Encipher[4] = m[3];
    Encipher[5] = m[2];
    Encipher[6] = m[1];
    Encipher[7] = m[0];
}

private void TDes(byte orientation, byte[] PlainText, byte[] key,
        byte[] ucEncipher) {
    byte[] En = new byte[8];
    byte[] key1 = new byte[8];
    byte[] key2 = new byte[8];

    System.arraycopy(key, 0, key1, 0, 8);
    System.arraycopy(key, 8, key2, 0, 8);

    if (orientation == 0) {
        SDes((byte) 0, PlainText, key1, En);
        // printHex(En, 0, 8);

        SDes((byte) 1, En, key2, En);
        // printHex(En, 0, 8);

        SDes((byte) 0, En, key1, ucEncipher);
        // printHex(ucEncipher, 0, 8);
    } else {
        SDes((byte) 1, PlainText, key1, En);
        SDes((byte) 0, En, key2, En);
        SDes((byte) 1, En, key1, ucEncipher);
    }
}

public final int MAX_CI_LEN = 1024;

/**
 * 
 * @param key
 *            密鑰,16字節 ip + chinajiangxia 的前16字節作爲密鑰
 * 
 * @param plain_text
 *            明文
 * @param length
 *            待加密的長度,長度不允許超過1024字節
 * 
 * @return 返回加密後的字符串
 * @throws Exception
 */
public byte[] cipher2(byte[] key, byte[] plain_text, int length)
        throws Exception {

    byte[] t_plain = null;
    byte[] t_crypt = null;

    int en_cnt;
    int pad_cnt = 0;
    int i;

    if (length > MAX_CI_LEN) {
        throw new Exception(String.format("加密長度不允許超過%d字節", MAX_CI_LEN));
    }

    if (length % 8 == 0) {
        en_cnt = length / 8;
    } else {
        en_cnt = length / 8 + 1;
        pad_cnt = 8 - length % 8;
    }

    t_plain = new byte[length + pad_cnt];
    t_crypt = new byte[t_plain.length];
    Arrays.fill(t_plain, (byte) 0x0);
    System.arraycopy(plain_text, 0, t_plain, 0, length);

    for (i = 0; i < en_cnt; i++) {
        byte[] tPlain = new byte[8];
        byte[] tmpCpt = new byte[8];
        System.arraycopy(t_plain, 8 * i, tPlain, 0, 8);
        TDes((byte) 0, tPlain, key, tmpCpt);
        System.arraycopy(tmpCpt, 0, t_crypt, 8 * i, 8);
    }

    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    for (i = 0; i < 8 * en_cnt; i++) {
        byte[] x = String.format("%02x", t_crypt[i]).getBytes();
        bout.write(x);
    }

    return bout.toByteArray();
}

private byte asc_bcd(byte[] what) {
    byte digit;

    digit = (byte) (what[0] >= 'a' ? ((what[0]) - 'a') + 10
            : (what[0] - '0'));
    digit *= 16;
    digit += (what[1] >= 'a' ? ((what[1]) - 'a') + 10 : (what[1] - '0'));
    return (digit);
}

public byte[] decipher2(byte[] key, byte[] crypted_text, int length)
        throws IOException {
    byte[] t_crypt = new byte[MAX_CI_LEN];
    int i;

    for (i = 0; i < length / 2; i++) {
        byte[] tmp = new byte[2];
        tmp[0] = crypted_text[i * 2];
        tmp[1] = crypted_text[i * 2 + 1];

        t_crypt[i] = asc_bcd(tmp);
    }

    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    for (i = 0; i < length / 16; i++) {
        byte[] tmp = new byte[8];
        byte[] ret = new byte[8];
        System.arraycopy(t_crypt, 8 * i, tmp, 0, 8);
        TDes((byte) 1, tmp, key, ret);
        bout.write(ret);
    }

    // 去掉尾部0x0;
    byte[] tmp = bout.toByteArray();
    int end = tmp.length;
    for (; end >= 0; end--) {
        if (tmp[end - 1] != 0x0) {
            break;
        }
    }

    byte[] tmpNoZero = new byte[end];
    System.arraycopy(tmp, 0, tmpNoZero, 0, end);

    return tmpNoZero;
}

/**
 * 獲取密鑰,密鑰的算法爲使用客戶端IP地址(字符串), 不滿16(實際IP串最長爲15位),後面加yangpengit 補充爲16位
 * 
 * @param hip
 * @return
 */
public byte[] getKey(String hip) {
    String key = hip + DES_KEY;
    return key.substring(0, 16).getBytes();
}

/**
 * 
 * @param osName
 */
public void setOsName(String osName) {
    OS_NAME = osName;
}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章