⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.c

📁 c51写的DES加解密程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 重新安排S-box中数据顺序,如果输入的六位是000101,按DES标准的查询方式则是
 * 查第二行中的第三列数据。而此表中因为"000101"=5,则是查第六个数据得到"7"
 */
static unsigned char SBox_1[64]={
	14,0,4,15,13,7,1,4,
    2,14,15,2,11,13,8,1,
    3,10,10,6,6,12,12,11,
    5,9,9,5,0,3,7,8,
    4,15,1,12,14,8,8,2,
    13,4,6,9,2,1,11,7,
    15,5,12,11,9,3,7,14,
    3,10,10,0,5,6,0,13
};
static unsigned char SBox_2[64]={
	15,3,1,13,8,4,14,7,
    6,15,11,2,3,8,4,14,
    9,12,7,0,2,1,13,10,
    12,6,0,9,5,11,10,5,
    0,13,14,8,7,10,11,1,
    10,3,4,15,13,4,1,2,
    5,11,8,6,12,7,6,12,
    9,0,3,5,2,14,15,9
};
static unsigned char SBox_3[64]={
	10,13,0,7,9,0,14,9,
    6,3,3,4,15,6,5,10,
    1,2,13,8,12,5,7,14,
    11,12,4,11,2,15,8,1,
    13,1,6,10,4,13,9,0,
    8,6,15,9,3,8,0,7,
    11,4,1,15,2,14,12,3,
    5,11,10,5,14,2,7,12
};
static unsigned char SBox_4[64]={
 	7,13,13,8,14,11,3,5,
    0,6,6,15,9,0,10,3,
    1,4,2,7,8,2,5,12,
    11,1,12,10,4,14,15,9,
    10,3,6,15,9,0,0,6,
    12,10,11,1,7,13,13,8,
    15,9,1,4,3,5,14,11,
    5,12,2,7,8,2,4,14
};
static unsigned char SBox_5[64]={
 	2,14,12,11,4,2,1,12,
    7,4,10,7,11,13,6,1,
    8,5,5,0,3,15,15,10,
    13,3,0,9,14,8,9,6,
    4,11,2,8,1,12,11,7,
    10,1,13,14,7,2,8,13,
    15,6,9,15,12,0,5,9,
    6,10,3,4,0,5,14,3
};
static unsigned char SBox_6[64]={
 	12,10,1,15,10,4,15,2,
    9,7,2,12,6,9,8,5,
    0,6,13,1,3,13,4,14,
    14,0,7,11,5,3,11,8,
    9,4,14,3,15,2,5,12,
    2,9,8,5,12,15,3,10,
    7,11,0,14,4,1,10,7,
    1,6,13,0,11,8,6,13
};
static unsigned char SBox_7[64]={
 	4,13,11,0,2,11,14,7,
    15,4,0,9,8,1,13,10,
    3,14,12,3,9,5,7,12,
    5,2,10,15,6,8,1,6,
    1,6,4,11,11,13,13,8,
    12,1,3,4,7,10,14,7,
    10,9,15,5,6,0,8,15,
    0,14,5,2,9,3,2,12
};
static unsigned char SBox_8[64]={
 	13,1,2,15,8,13,4,8,
    6,10,15,3,11,7,1,4,
    10,12,9,5,3,6,14,11,
    5,0,0,14,12,9,7,2,
    7,2,11,1,4,14,1,7,
    9,4,12,10,14,8,2,13,
    0,15,6,12,10,9,13,0,
    15,3,3,5,5,6,8,11
};

/*
 * 0(行)   57,49,41,33,25,17, 9, 1,
 * 1       58,50,42,34,26,18,10, 2,
 * 2       59,51,43,35,27,19,11, 3,
 * 3       60,52,44,36,63,55,47,39,
 * 4       31,23,15, 7,62,54,46,38,
 * 5       30,22,14, 6,61,53,45,37,
 * 6       29,21,13, 5,28,20,12, 4
 *  譬如1换到了第8位,在下面的数组中表示为是{0x00,0x01},0x00表示与新key数组中的
 *  第"0"号key或运算,当然或上的是"0x01",即key[0x00] |= 0x01
 *  转换算法中将采用左移位运算,每移一位则在下表中查询是否应“或”操作key数组中
 *  的某一个key
 */
static unsigned char Key_64_To_56_Tab[64][2]={
	{0x00,0x01},	// 1
    {0x01,0x01},	// 2
    {0x02,0x01},	// 3
    {0x06,0x01},	// 4
    {0x06,0x10},	// 5
    {0x05,0x10},	// 6
    {0x04,0x10},	// 7
    {0x00,0x00},	// 8	no use

    {0x00,0x02},	// 9
    {0x01,0x02},	// 10
    {0x02,0x02},	// 11
    {0x06,0x02},	// 12
    {0x06,0x20},	// 13
    {0x05,0x20},	// 14
    {0x04,0x20},	// 15
    {0x00,0x00},	// 16

    {0x00,0x04},	// 17
    {0x01,0x04},	// 18
	{0x02,0x04},	// 19
    {0x06,0x04},	// 20
    {0x06,0x40},	// 21
    {0x05,0x40},	// 22
    {0x04,0x40},	// 23
    {0x00,0x00},	// 24

    {0x00,0x08},	// 25
    {0x01,0x08},	// 26
    {0x02,0x08},	// 27
	{0x06,0x08},	// 28
    {0x06,0x80},	// 29
    {0x05,0x80},	// 30
    {0x04,0x80},	// 31
    {0x00,0x00},	// 32

    {0x00,0x10},	// 33
    {0x01,0x10},	// 34
    {0x02,0x10},	// 35
    {0x03,0x10},	// 36
    {0x05,0x01},	// 37
    {0x04,0x01},	// 38
    {0x03,0x01},	// 39
	{0x00,0x00},	// 40

    {0x00,0x20},	// 41
    {0x01,0x20},	// 42
    {0x02,0x20},	// 43
    {0x03,0x20},	// 44
    {0x05,0x02},	// 45
    {0x04,0x02},	// 46
    {0x03,0x02},	// 47
    {0x00,0x00},	// 48

    {0x00,0x40},	// 49
    {0x01,0x40},	// 50
    {0x02,0x40},	// 51
    {0x03,0x40},	// 52
	{0x05,0x04},	// 53
    {0x04,0x04},	// 54
    {0x03,0x04},	// 55
    {0x00,0x00},	// 56

    {0x00,0x80},	// 57
    {0x01,0x80},	// 58
    {0x02,0x80},	// 59
    {0x03,0x80},	// 60
    {0x05,0x08},	// 61
    {0x04,0x08},	// 62
	{0x03,0x08},	// 63
    {0x00,0x00}		// 64
};

/* 64-bit key convert to 56-bit key with compressed-convert */
extern void Key64_To_56(unsigned char Key_64[],unsigned char Key_56[]) {
    unsigned char i,j,deal_data;
	unsigned char index=0;
	unsigned char NewKey_index,NewKey_data;

	for (i=0;i<7;i++)
    	Key_56[i]=0;
	for (i=0;i<8;i++) {
    	deal_data=Key_64[i];
        for (j=0;j<7;j++) {		// only cycle 7 times is enough
			if ((deal_data & 0x80)==0x80) {
    			NewKey_index=Key_64_To_56_Tab[index][0];
                NewKey_data=Key_64_To_56_Tab[index][1];
				Key_56[NewKey_index] |= NewKey_data;
            }
			index++;
            deal_data <<= 1;
        }
        index++;
    }
}
/*
 * 将56bits的key共7个字节分成左右两半各28 bits,然后分别循环"cyc_times"次,
 * 循环方向由"di"值确定:
 * 若di=0, 向左循环,用于加密
 *   di=1, 向右循环,用于解密
 */
void KeyRotate(unsigned char Key_56[],unsigned char cyc_times,unsigned char di) {
	unsigned char temp1,temp2;
	char i,j;

    for (i=0;i<cyc_times;i++) {
        if (di==0) {		/* 向左循环 1 bit */
			temp1=0;
			for (j=6;j>=0;j--) {
    	    	temp2=Key_56[j];
				Key_56[j]<<=1;
				Key_56[j] |= ((temp1>>7) & 0x01);
				temp1=temp2;
        	}
            /* Key_56[6].0 must be 0, so not to add "Key[6] &= 0xfe" */
            Key_56[6] |= ( (Key_56[3]>>4) & 0x01);
			Key_56[3] &= 0xef;
            Key_56[3] |= ( (temp2>>3) & 0x10);
        }
        else {              /* 向右循环 1 bit */
        	temp1=0;
			for (j=0;j<7;j++) {
    	    	temp2=Key_56[j];
				Key_56[j]>>=1;
				Key_56[j] |= ((temp1<<7) & 0x80);
				temp1=temp2;
        	}
            /* Key_56[0].7 must be 0, so not to add "Key[6] &= 0xfe"  */
            Key_56[0] |= ( (Key_56[3]<<4) & 0x80);
			Key_56[3] &= 0xf7;
            Key_56[3] |= ( (temp2<<3) & 0x08);
        }
    }
}
/*
 * 0(行)   14,17,11,24, 1, 5, 3,28,
 * 1       15, 6,21,10,23,19,12, 4,
 * 2       26, 8,16, 7,27,20,13, 2,
 * 3	   41,52,31,37,47,55,30,40,
 * 4       51,45,33,48,44,49,39,56,
 * 5       34,53,46,42,50,36,29,32
 */
static unsigned char Key_56_To_48_Tab[56][2]={
	{0x00,0x08},	/* 1 */
    {0x02,0x01},	/* 2 */
    {0x00,0x02},	/* 3 */
    {0x01,0x01},	/* 4 */
    {0x00,0x04},	/* 5 */
    {0x01,0x40},	/* 6 */
    {0x02,0x10},	/* 7 */
    {0x02,0x40},	/* 8 */

    {0x00,0x00},
    {0x01,0x10},	/* 10 */
    {0x00,0x20},	/* 11 */
    {0x01,0x02},	/* 12 */
    {0x02,0x02},	/* 13 */
    {0x00,0x80},	/* 14 */
    {0x01,0x80},	/* 15 */
    {0x02,0x20},	/* 16 */

    {0x00,0x40},	/* 17 */
    {0x00,0x00},
    {0x01,0x04},	/* 19 */
    {0x02,0x04},	/* 20 */
    {0x01,0x20},	/* 21 */
    {0x00,0x00},
    {0x01,0x08},	/* 23 */
    {0x00,0x10},	/* 24 */

    {0x00,0x00},
    {0x02,0x80},	/* 26 */
    {0x02,0x08},	/* 27 */
    {0x00,0x01},	/* 28 */
    {0x05,0x02},	/* 29 */
    {0x03,0x02},	/* 30 */
    {0x03,0x20},	/* 31 */
    {0x05,0x01},	/* 32 */

    {0x04,0x20},	/* 33 */
    {0x05,0x80},	/* 34 */
    {0x00,0x00},
    {0x05,0x04},	/* 36 */
    {0x03,0x10},	/* 37 */
    {0x00,0x00},
    {0x04,0x02},	/* 39 */
    {0x03,0x01},	/* 40 */

    {0x03,0x80},	/* 41 */
    {0x05,0x10},	/* 42 */
    {0x00,0x00},
	{0x04,0x08},	/* 44 */
    {0x04,0x40},	/* 45 */
    {0x05,0x20},	/* 46 */
    {0x03,0x80},	/* 47 */
    {0x04,0x10},	/* 48 */

    {0x04,0x04},	/* 49 */
    {0x05,0x08},	/* 50 */
    {0x04,0x80},	/* 51 */
    {0x03,0x40},	/* 52 */
    {0x05,0x40},	/* 53 */
    {0x00,0x00},
    {0x03,0x04},	/* 55 */
    {0x04,0x01}		/* 56 */
};

/*
 *  56位的密码经过分组循环后,重新组成56位密码,然后通过压缩变换获得48位的
 *  压缩置换密码,本函数目的就是为获得此压缩的48位密码,以便与通过S盒获得的
 *  数进行"OR" 运算
 */
void Key_56_To_48(unsigned char Key_56[],unsigned char Key_48[]) {
    unsigned char i,j,deal_data;
	unsigned char index=0;
	unsigned char NewKey_index,NewKey_data;

	for (i=0;i<6;i++)
    	Key_48[i]=0;
	for (i=0;i<7;i++) {
    	deal_data=Key_56[i];
        for (j=0;j<8;j++) {
			if ((deal_data & 0x80)==0x80) {
    			NewKey_index=Key_56_To_48_Tab[index][0];
                NewKey_data=Key_56_To_48_Tab[index][1];
				Key_48[NewKey_index] |= NewKey_data;
            }
			index++;
            deal_data <<= 1;
        }
    }
}

unsigned char *SBox_Tab[]={
	SBox_1,
	SBox_2,
	SBox_3,
	SBox_4,
	SBox_5,
	SBox_6,
	SBox_7,
	SBox_8
};

/*
 *  48-bits 输进S-盒,获得32-bits的输出
 *  输出结果仍旧放进data[]
 */
extern void S_Box_Replace(unsigned char in_data[]) {
	unsigned char out_data[8],temp_data;
    unsigned char *ptr;
    char i,j,k;

    for (i=0;i<8;i++) {		/* 分别处理8个S-盒*/
    	temp_data=(in_data[0]>>2);
        temp_data &= 0x3f;		/* 获得即将去查表的索引值 */
        for (j=0;j<6;j++) {		/* 准备向左循环6次 */
        	for (k=0;k<5;k++) {	/* 每次循环6个bytes都要动 */
            	in_data[k]<<=1;
                in_data[k]|=((in_data[k+1]>>7) & 0x01);
            }
			in_data[5]<<=1;		/* 最后一个字节与前面的操作有区别*/
        }
        ptr=(unsigned char *)&SBox_Tab[i][0];
        //*ptr=(unsigned char *)SBox_Tab[i];		/* 指向第i个S-盒的转换表*/
		//out_data[i]=(*ptr)[temp_data];	/* 获得转换数据 */
		out_data[i]=(ptr)[temp_data];	/* 获得转换数据 */
    }
	for (i=0;i<4;i++) {
    	in_data[i]=( (out_data[2*i]<<4) | out_data[2*i+1]);
    }
}

/*
 //  0    32  01  02  03  04  05  04  05
 //  1    06  07  08  09  08  09  10  11
 //  2    12  13  12  13  14  15  16  17
 //  3    16  17  18  19  20  21  20  21
 //  4    22  23  24  25  24  25  26  27
 //  5    28  29  28  29  30  31  32  01
 *   ------------------------------------
 *   01分别在第0行及第5行存在,第0行的最后要和0x40或,第5行的最后要和0x01或
 */
static unsigned char Data_32_To_48_Tab[32][4]={
	{0x00,0x40,0x05,0x01},	/* 1 */
    {0x00,0x20,0x00,0x00},	/* 2 */
    {0x00,0x10,0x00,0x00},	/* 3 */
    {0x00,0x08,0x00,0x02},	/* 4 */
    {0x00,0x04,0x00,0x01},	/* 5 */
    {0x01,0x80,0x00,0x00},	/* 6 */
    {0x01,0x40,0x00,0x00},	/* 7 */
    {0x01,0x20,0x01,0x08},	/* 8 */

    {0x01,0x10,0x01,0x04},	/* 9 */
    {0x01,0x02,0x00,0x00},	/* 10 */
    {0x01,0x01,0x00,0x00},	/* 11 */
    {0x02,0x80,0x02,0x20},	/* 12 */
    {0x02,0x40,0x02,0x10},	/* 13 */
    {0x02,0x08,0x00,0x00},	/* 14 */
    {0x02,0x04,0x00,0x00},	/* 15 */
    {0x02,0x02,0x03,0x80},	/* 16 */

    {0x02,0x01,0x03,0x40},	/* 17 */
    {0x03,0x20,0x00,0x00},	/* 18 */
    {0x03,0x10,0x00,0x00},	/* 19 */
    {0x03,0x08,0x03,0x02},	/* 20 */
    {0x03,0x04,0x03,0x01},	/* 21 */
    {0x04,0x80,0x00,0x00},	/* 22 */
    {0x04,0x40,0x00,0x00},	/* 23 */
    {0x04,0x20,0x04,0x08},	/* 24 */

    {0x04,0x10,0x04,0x04},	/* 25 */
    {0x04,0x02,0x00,0x00},	/* 26 */
    {0x04,0x01,0x00,0x00},	/* 27 */
    {0x05,0x80,0x05,0x20},	/* 28 */
    {0x05,0x40,0x05,0x10},	/* 29 */
    {0x05,0x08,0x00,0x00},	/* 30 */
    {0x05,0x04,0x00,0x00},	/* 31 */
    {0x05,0x02,0x00,0x80} 	/* 32 */
};
/*
 *  将32-bits的数据扩展成48-bits的数据位准备与48-bits的密码异或
 *  本函数正是为了扩展的目的 : 32-bits  ==>  48-bits
 *  input  :  Plain_32[4]
 *  output :  Plain_48[6]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -