关于DES算法的一些入门

对称密钥算法又分为两种:分组密码和流密码。分组密码将明文分割为若干个定长的数据块(称为一个分组),每次 对一个分组进行处理;流密码又称序列密码,依次对输入每个元素进行处理。

DES是对称秘钥算法,且是分组秘钥算法,它主要是经过一系列的置换变换和异或相加,

首先我得知道,DES的解密算法与加密算法完全相同,只需要将密钥的应用次序与加密时相反应用即可。即解密过程是初始置换函数IP接受长度为64比特的密文输入,将16个子密钥按照K16到K1的顺序应用与函数F的16轮迭代运算中,然后将迭代的结果经由末置换函数IP-1得到64位的明文输出

主要可以分为下面四个步骤:

1.初始置换函数 IP(InitDataValue)

private int[] InitDataValue(int[] data){
		int[] dataValue = new int[64];
		for(int i=0;i<64;i++){
			dataValue[i] = data[ DATA_IP[i] - 1 ];
		}
		return dataValue;
	} 
private static final int[] DATA_IP = {
		58, 50, 42, 34, 26, 18, 10, 2, 
        60, 52, 44, 36, 28, 20, 12, 4, 
        62, 54, 46, 38, 30, 22, 14, 6, 
        64, 56, 48, 40, 32, 24, 16, 8, 
        57, 49, 41, 33, 25, 17, 9,  1, 
        59, 51, 43, 35, 27, 19, 11, 3, 
        61, 53, 45, 37, 29, 21, 13, 5, 
        63, 55, 47, 39, 31, 23, 15, 7
	};	//64

2.子秘钥Ki的获取。

//生成16个 子秘钥
	private void InitKeyValue(int[] key, int[][] keyArray){
		int[] keyTemp = new int[56];
		for(int i=0;i<56;i++){
			keyTemp[i] = key[ KEY_PC_1[i] - 1];
		}
		//生成16个子秘钥
		for(int i=0; i<16; i++){
			// 左移秘钥是 56 位的
			LEFT_MOVE( keyTemp, MOVE_LEFT[i] );
			for(int j=0; j<48; j++){
				keyArray[i][j] = keyTemp[ KEY_PC_2[j] - 1 ];
			}
		}
	}
	// 秘钥左移函数
	private void LEFT_MOVE(int[] key, int offset){
		int[] keyLeft = new int[28];
		int[] keyRight = new int[28];
		int[] keyLeftTemp = new int[28];
		int[] keyRightTemp = new int[28]; 
		for(int i=0; i<28; i++){
			keyLeft[i] = key[i];
			keyRight[i] = key[i+28];
		}
		if(offset == 1){
			for(int i=0;i<27;i++){
				keyLeftTemp[i] = keyLeft[ i+1 ];
				keyRightTemp[i] = keyRight[ i+1 ];
			}
			keyLeftTemp[27] = keyLeft[0];
			keyRightTemp[27] = keyRight[0];
		}else if(offset == 2){
			for(int i=0;i<26;i++){
				keyLeftTemp[i] = keyLeft[ i+2 ];
				keyRightTemp[i] = keyRight[ i+2 ];
			}
			keyLeftTemp[26] = keyLeft[0];
			keyRightTemp[26] = keyRight[0];
			keyLeftTemp[27] = keyLeft[1];
			keyRightTemp[27] = keyRight[1];
		}
		// 重新组织 key 数组
		for (int i=0; i<28; i++) {
            key[i] = keyLeftTemp[i];
            key[i+28] = keyRightTemp[i];
        }
	}

3.加密解密函数(这个最重要)

// 秘钥函数F, 接受32位 数据和48位秘钥的输入 , 包含S盒运算的整个过程
	private void loopF(int[] dataValue, int times, int flag, int[][] keyArray){
		int[] leftData = new int[32];
		int[] rightData = new int[32];
		int[] leftDataTemp = new int[32];
		int[] rightDataTemp = new int[32];
		int[] temp = new int[48];	//作为 中转的 48位数组存放过程
		int[] sBoxData = new int[8];
		int[] SValue = new int[32];
		int[][] SboxTemp = new int[8][6];
		int[] S_PValue = new int[32];
		for(int i=0;i<32;i++){
			leftData[i] = dataValue[i];
			rightData[i] = dataValue[ i+32 ];
		}
		for(int i=0; i<48; i++){
//			temp[i] = dataValue[ E[i] - 1 ];
			temp[i] = rightData[ E[i] - 1 ];
			//将上面的结果 同 48位秘钥Ki 做异或运算
			temp[i] = temp[i] + keyArray[times][i];
			if(temp[i] == 2)
				temp[i] = 0;
		}
		//分组成8份
		for(int i=0; i<8; i++){
			for(int j=0; j<6; j++){
				SboxTemp[i][j] = temp[ (i*6) + j ];
			}
			//做S盒变换
			sBoxData[i] = S_BOX[i]
					[ (SboxTemp[i][0]<<1) + SboxTemp[i][5] ]		//取第一位和第六位组合成X
					[ (SboxTemp[i][1]<<3) + (SboxTemp[i][2]<<2) + (SboxTemp[i][3]<<1) +SboxTemp[i][4] ];	//取第2-5位作为Y
			//换成二进制的  4位数
			for(int j=0; j<4; j++ ){
				SValue[((i * 4) + 3) - j] = sBoxData[i] % 2;
				sBoxData[i] = sBoxData[i] / 2;
			}
		}
		for(int i=0; i<32; i++){
			S_PValue[i] = SValue[ P[i] - 1 ];	//存储经过P置换的值
			leftDataTemp[i] = rightData[i]; 	// 右边移到左边
			rightDataTemp[i] = leftData[i] + S_PValue[i];
			if( rightDataTemp[i] ==2 )
				rightDataTemp[i] = 0;
			//重新组合 密文
			if( ((flag == 0) && (times == 0)) || ((flag == 1) && (times == 15)) ){
				dataValue[i] = rightDataTemp[i];
				dataValue[i+32] = leftDataTemp[i]; 
			}else{
				dataValue[i] = leftDataTemp[i];
				dataValue[i+32] = rightDataTemp[i];
			}
		}
	}
4.末置换函数IP-1

private int[] FinalDataValue(int[] data){
		int[] dataValue = new int[64];
		for(int i=0;i<64;i++){
			dataValue[i] = data[ DATA_IP_1[i] - 1 ];
		}
		return dataValue;
	}


经过上面的算法,我们知道算法的输入和输出都是64bit的数据,一般我们的输入是 byte[ ]、String,这里就需要进行数据转换,笔者对这里有点不理解??加密之后,密文出现乱码。但是解密之后,又出现了正常明文~~囧。。。

还有一点就是数据处理的时候每次都是8bytes处理,并且当数据不是8bytes的时候需要补位。这里笔者还不知道怎么处理。。继续研究一下

明白了DES的原理之后,我们可以展望一下3DES算法。

        从Data和Key的输入,可以分为3DES和DES两种,也就是复杂度不同。

3DES加密过程为:C=Ek3(Dk2(Ek1(P))),3DES解密过程为:P=Dk1(EK2(Dk3(C)))。其中P为明文,C为密文,E()为加密函数,D()为解密函数。

下面贴出根据别人代码总结的代码:

public class DES {
	byte[] key;
	public DES(String key){
		this.key = key.getBytes();
	}
	// 加密数据 开始置换的数组
	private static final int[] DATA_IP = {
		58, 50, 42, 34, 26, 18, 10, 2, 
        60, 52, 44, 36, 28, 20, 12, 4, 
        62, 54, 46, 38, 30, 22, 14, 6, 
        64, 56, 48, 40, 32, 24, 16, 8, 
        57, 49, 41, 33, 25, 17, 9,  1, 
        59, 51, 43, 35, 27, 19, 11, 3, 
        61, 53, 45, 37, 29, 21, 13, 5, 
        63, 55, 47, 39, 31, 23, 15, 7
	};	//64
	// 加密数据 最后的置换数组
	private static final int[] DATA_IP_1 = {
		40, 8, 48, 16, 56, 24, 64, 32, 
		39, 7, 47, 15, 55, 23, 63, 31,
		38, 6, 46, 14, 54, 22, 62, 30,
		37, 5, 45, 13, 53, 21, 61, 29,
		36, 4, 44, 12, 52, 20, 60, 28,
		35, 3, 43, 11, 51, 19, 59, 27,
		34, 2, 42, 10, 50, 18, 58, 26,
		33, 1, 41, 9,  49, 17, 57, 25,
	};	//64
	// 初始秘钥置换函数, 变成56位
	private static final int[] KEY_PC_1 = {
	   57, 49, 41, 33, 25, 17, 9,  
        1, 58, 50, 42, 34, 26, 18, 
       10,  2, 59, 51, 43, 35, 27, 
       19, 11,  3, 60, 52, 44, 36, 
       63, 55, 47, 39, 31, 23, 15,  
        7, 62, 54, 46, 38, 30, 22, 
       14,  6, 61, 53, 45, 37, 29, 
       21, 13,  5, 28, 20, 12,  4
	};	//56
	//获得的秘钥  进行的压缩和置换, 生成16组子秘钥必须的函数
	private static final int[] KEY_PC_2 = {
	   14, 17, 11, 24,  1,  5, 
        3, 28, 15,  6, 21, 10, 
       23, 19, 12,  4, 26,  8, 
       16,  7, 27, 20, 13,  2, 
       41, 52, 31, 37, 47, 55, 
       30, 40, 51, 45, 33, 48, 
       44, 49, 39, 56, 34, 53, 
       46, 42, 50, 36, 29, 32
	};	//48
	// 循环左移函数,用于生成16个子秘钥
	private static final int[] MOVE_LEFT = {
		1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
	};
	// E盒运算, 扩展函数, 用于扩展 Ri(秘钥的右半部分), 生成 16 个子秘钥  E(Ri)
	private static final int[] E = {
		32,  1,  2,  3,  4,  5, 
        4,   5,  6,  7,  8,  9, 
        8,   9, 10, 11, 12, 13, 
        12, 13, 14, 15, 16, 17, 
        16, 17, 18, 19, 20, 21, 
        20, 21, 22, 23, 24, 25, 
        24, 25, 26, 27, 28, 29, 
        28, 29, 30, 31, 32,  1
	};
	// P盒运算 用于参加16个子秘钥的运算。
	private static final int[] P = {
		16,  7, 20, 21, 
        29, 12, 28, 17,
         1, 15, 23, 26, 
         5, 18, 31, 10, 
         2,  8, 24, 14, 
         32, 27, 3,  9, 
         19, 13, 30, 6, 
         22, 11,  4, 25
	};
	// S盒函数, 这个函数用于 组成 半边子秘钥 取 1和6位 为X 取2345为Y, 找到对应的值, 刚好8组
	private static final int[][][] S_BOX = {
		{// S_Box[1]   OK
            { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
            { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
            { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
            { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
        },
        { // S_Box[2]  OK
            { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
            { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
            { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
            { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
        },
        { // S_Box[3]  OK
            { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
            { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
            { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
            { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
        },
        { // S_Box[4]  OK
            { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
            { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
            { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
            { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
        },
        { // S_Box[5] OK
            { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
            { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
            { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
            { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
        },
        { // S_Box[6] OK
            { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
            { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
            { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
            { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
        },
        { // S_Box[7] OK
            { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
            { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
            { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
            { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
        },
        { // S_Box[8] OK
            { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
            { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
            { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
            { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
        } 
	};
	
	/** 第一步,生成初始化 置换数据 数组 */
	private int[] InitDataValue(int[] data){
		int[] dataValue = new int[64];
		for(int i=0;i<64;i++){
			dataValue[i] = data[ DATA_IP[i] - 1 ];
		}
		return dataValue;
	} 
	/** 第二步,生成子秘钥 */
	//生成16个 子秘钥
	private void InitKeyValue(int[] key, int[][] keyArray){
		int[] keyTemp = new int[56];
		for(int i=0;i<56;i++){
			keyTemp[i] = key[ KEY_PC_1[i] - 1];
		}
		//生成16个子秘钥
		for(int i=0; i<16; i++){
			// 左移秘钥是 56 位的
			LEFT_MOVE( keyTemp, MOVE_LEFT[i] );
			for(int j=0; j<48; j++){
				keyArray[i][j] = keyTemp[ KEY_PC_2[j] - 1 ];
			}
		}
	}
	// 秘钥左移函数
	private void LEFT_MOVE(int[] key, int offset){
		int[] keyLeft = new int[28];
		int[] keyRight = new int[28];
		int[] keyLeftTemp = new int[28];
		int[] keyRightTemp = new int[28]; 
		for(int i=0; i<28; i++){
			keyLeft[i] = key[i];
			keyRight[i] = key[i+28];
		}
		if(offset == 1){
			for(int i=0;i<27;i++){
				keyLeftTemp[i] = keyLeft[ i+1 ];
				keyRightTemp[i] = keyRight[ i+1 ];
			}
			keyLeftTemp[27] = keyLeft[0];
			keyRightTemp[27] = keyRight[0];
		}else if(offset == 2){
			for(int i=0;i<26;i++){
				keyLeftTemp[i] = keyLeft[ i+2 ];
				keyRightTemp[i] = keyRight[ i+2 ];
			}
			keyLeftTemp[26] = keyLeft[0];
			keyRightTemp[26] = keyRight[0];
			keyLeftTemp[27] = keyLeft[1];
			keyRightTemp[27] = keyRight[1];
		}
		// 重新组织 key 数组
		for (int i=0; i<28; i++) {
            key[i] = keyLeftTemp[i];
            key[i+28] = keyRightTemp[i];
        }
	}
	/** 第三步,秘钥函数 F */
	// 秘钥函数F, 接受32位 数据和48位秘钥的输入 , 包含S盒运算的整个过程
	private void loopF(int[] dataValue, int times, int flag, int[][] keyArray){
		int[] leftData = new int[32];
		int[] rightData = new int[32];
		int[] leftDataTemp = new int[32];
		int[] rightDataTemp = new int[32];
		int[] temp = new int[48];	//作为 中转的 48位数组存放过程
		int[] sBoxData = new int[8];
		int[] SValue = new int[32];
		int[][] SboxTemp = new int[8][6];
		int[] S_PValue = new int[32];
		for(int i=0;i<32;i++){
			leftData[i] = dataValue[i];
			rightData[i] = dataValue[ i+32 ];
		}
		for(int i=0; i<48; i++){
//			temp[i] = dataValue[ E[i] - 1 ];
			temp[i] = rightData[ E[i] - 1 ];
			//将上面的结果 同 48位秘钥Ki 做异或运算
			temp[i] = temp[i] + keyArray[times][i];
			if(temp[i] == 2)
				temp[i] = 0;
		}
		//分组成8份
		for(int i=0; i<8; i++){
			for(int j=0; j<6; j++){
				SboxTemp[i][j] = temp[ (i*6) + j ];
			}
			//做S盒变换
			sBoxData[i] = S_BOX[i]
					[ (SboxTemp[i][0]<<1) + SboxTemp[i][5] ]		//取第一位和第六位组合成X
					[ (SboxTemp[i][1]<<3) + (SboxTemp[i][2]<<2) + (SboxTemp[i][3]<<1) +SboxTemp[i][4] ];	//取第2-5位作为Y
			//换成二进制的  4位数
			for(int j=0; j<4; j++ ){
				SValue[((i * 4) + 3) - j] = sBoxData[i] % 2;
				sBoxData[i] = sBoxData[i] / 2;
			}
		}
		for(int i=0; i<32; i++){
			S_PValue[i] = SValue[ P[i] - 1 ];	//存储经过P置换的值
			leftDataTemp[i] = rightData[i]; 	// 右边移到左边
			rightDataTemp[i] = leftData[i] + S_PValue[i];
			if( rightDataTemp[i] ==2 )
				rightDataTemp[i] = 0;
			//重新组合 密文
			if( ((flag == 0) && (times == 0)) || ((flag == 1) && (times == 15)) ){
				dataValue[i] = rightDataTemp[i];
				dataValue[i+32] = leftDataTemp[i]; 
			}else{
				dataValue[i] = leftDataTemp[i];
				dataValue[i+32] = rightDataTemp[i];
			}
		}
	}
	/** 第四步,最后置换函数  */
	private int[] FinalDataValue(int[] data){
		int[] dataValue = new int[64];
		for(int i=0;i<64;i++){
			dataValue[i] = data[ DATA_IP_1[i] - 1 ];
		}
		return dataValue;
	}
	
	/**	执行 “加密-解密” 操作
     * @param timeData (int[64])二进制加密数据
     * @param flag 1或0,1为加密,0为解密
     * @param keyarray new int[16][48]
     * @return 长度为8的字节数组
     */
	private byte[] EncryptMain(int[] timeData, int flag, int[][] keyarray) {
        byte[] encrypt = new byte[8];
        int flags = flag;
        int[] M = new int[64];		//明文数组
        int[] MIP_1 = new int[64];	

        M = InitDataValue(timeData);	//初始化密文 IP
        
        if (flags == 1) { // 加密
            for (int i=0; i < 16; i++) {
            	loopF(M, i, flags, keyarray);//S盒处理
            }
        } else if (flags == 0) { // 解密
            for (int i = 15; i > -1; i--) {
            	loopF(M, i, flags, keyarray);//S盒处理
            }
        }
        
        MIP_1 = FinalDataValue(M);	//处理 IP_1
        
        //将(int[64]二进制数据字节数组,经过IP、S盒、IP-1处理后,得到的新的)int[64]二进制数据字节数组转换成byte[8]的字节数组
        GetEncryptResultOfByteArray(MIP_1, encrypt);
        // 返回加密数据
        return encrypt;
    }
	/**----------------------上面的是算法,下面的是输入的问题--------------------------*/

    /**	加密解密(主要方法)
     * @param des_key 密钥字节数组
     * @param des_data 要处理的数据字节数组
     * @param flag (1或0),1为加密,0为解密
     * @return 处理后的数据
     */
    private byte[] DesEncrypt(byte[] des_key, byte[] des_data, int flag) {
    	byte[] format_data = ByteDataFormat(des_data);		//补齐原始数据字节数组的长度为8的倍数,不足元素用0补
        byte[] format_key = ByteDataFormat(des_key);		//补齐密钥字节数组的长度为8的倍数,不足元素用0补
        int datalen = format_data.length;						//补齐后的原始数据字节数组的长度
        int unitcount = datalen / 8;							//补齐后的原始数据字节数组长度是8的多少倍
        byte[] result_data = new byte[datalen];					//用于盛放加密后的结果
        //每一次循环,都操作8个字节(加密解密)
        for (int i = 0; i < unitcount; i++) {
            byte[] tmpkey = new byte[8];			//真正起作用的密钥字节数组,只有8个字节
            byte[] tmpdata = new byte[8];			//用于参与操作的数据字节数组,只有8个字节
            System.arraycopy(format_key, i * 8, tmpkey, 0, 8);
            System.arraycopy(format_data, i * 8, tmpdata, 0, 8);
            byte[] tmpresult = UnitDes(tmpkey, tmpdata, flag);		//执行操作
            System.arraycopy(tmpresult, 0, result_data, i * 8, 8);
        }
        return result_data;
    }
    
    /** @param des_key 8个字节的密钥字节数组
     * @param des_data 8个字节的数据字节数组
     * @param flag 1或0,1为加密,0为解密
     * @return 8个字节的字节数组
     */
    private byte[] UnitDes(byte[] des_key, byte[] des_data, int flag) {
        // 检测输入参数格式是否正确,错误直接返回空值(null)
        if ((des_key.length != 8) ||  (des_data.length != 8) || ((flag != 1) && (flag != 0))) {
            throw new RuntimeException("Data Format Error !");
        }
        int flags = flag;
        int[] keyData = new int[64];	        // 二进制加密密钥
        int[] encryptdata = new int[64];        // 二进制加密数据
        byte[] EncryptCode = new byte[8];        // 加密操作完成后的字节数组
        int[][] KeyArray = new int[16][48];		        // 密钥初试化成二维数组
        
        // 将密钥字节数组转换成二进制字节数组
        keyData = ReadDataToBirnaryIntArray(des_key);
        // 将加密数据字节数组转换成二进制字节数组
        encryptdata = ReadDataToBirnaryIntArray(des_data);
        // 初试化密钥为二维密钥数组 (3个子秘钥全部都初始化了)
        InitKeyValue(keyData, KeyArray);
//         执行加密解密操作
        EncryptCode = EncryptMain(encryptdata, flags, KeyArray);
        return EncryptCode;
    }
    
    /** DES加密
     * @param data 原始数据(长度不能超过9999位)
     * @return 加密后的数据字节数组
     */
    public byte[] encrypt(String data){		//先不考虑填充问题
	     byte[] bytekey = key;
	     byte[] bytedata = data.getBytes();
	     byte[] result = new byte[data.length()];
	     result = DesEncrypt(bytekey, bytedata, 1);
	     return result;
    }
    
    /** DES解密
     * @param encryptData 加密后的数据字节数组
     * @return 还原后的数据字符串
     */
    public byte[] decrypt(byte[] encryptData){
        byte[] bytekey = key;
        //这里还得注意一下填充问题,先不考虑填充问题
        byte[] result = new byte[encryptData.length];
        result = DesEncrypt(bytekey, encryptData, 0);	//解密处理
        
        return result;
   }
    
    /**
     * 格式化字节数组,使其的长度为8的倍数,那些不足的部分元素用0填充
     * @return 一个新的字节数组,其长度比原数组长1-8位	(在byte的情况增加了7位,好像并没有表现出来)
     */
    private byte[] ByteDataFormat(byte[] data) {
        int len = data.length;
        int newlen;
        int padlen = 8 - (len % 8);		//要格式化的字节数组的长度与8的倍数的差值
        if(padlen !=8 ){
        	newlen = len + padlen;
        }else{
        	newlen = len;
        }
        byte[] newdata = new byte[newlen];
        System.arraycopy(data, 0, newdata, 0, len);
        for (int i = len; i < newlen; i++)
            newdata[i] = 0;
        return newdata;
    }
    
    /** 转换8个字节长度的数据字节数组为二进制数组
     * (一个字节转换为8个二进制)
     * @param intdata 8个字节的数据字节数组
     * @return 长度为64的二进制数组
     */
    private int[] ReadDataToBirnaryIntArray(byte[] intdata) {
        int i;
        int j;
        // 将数据转换为二进制数,存储到数组	(这里我真是觉得很蛋疼啊??~~直接变成了16位)
        int[] IntDa = new int[8];
        for (i = 0; i < 8; i++) {
            IntDa[i] = intdata[i];		//intdata[i]为byte,范围是-128~127
            if (IntDa[i] < 0) {			//故:IntDa[i]范围是-128~127
                IntDa[i] += 256;		//IntDa[i]永远不会超过256
                IntDa[i] %= 256;		//所以该处不需要取模,取模后结果还是自己
            }
        }
        
        int[] IntVa = new int[64];
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;
                IntDa[i] = IntDa[i] / 2;
            }
        }
        return IntVa;
    }
    
    /**	int[64]二进制数据字节数组转换成byte[8]的字节数组
     * @param data int[64]二进制数据字节数组
     * @param value byte[8] byte[8]的字节数组
     */
    private void GetEncryptResultOfByteArray(int[] data, byte[] value) {
        int i;
        int j;
        // 将存储64位二进制数据的数组中的数据转换为八个整数(byte)
        for (i = 0; i < 8; i++) {
            for (j = 0; j < 8; j++) {
                value[i] += (byte)(data[(i << 3) + j] << (7 - j));
            }
        }
        for (i = 0; i < 8; i++) {
            value[i] %= 256;
            if (value[i] > 128) {
                value[i] -= 255;
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值