http://hi.baidu.com/493168771/blog/item/5816b034ca19fc44251f144c.html
#include "stdio.h"
#include "time.h"
#include "stdlib.h"
#define PLAIN_FILE_OPEN_ERROR -1
#define KEY_FILE_OPEN_ERROR -2
#define CIPHER_FILE_OPEN_ERROR -3
#define OK 1
typedef char ElemType
/* 初始置换表IP */前散
int IP_Table[64] = { 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,
56,48,40,32,24,16,8,0,
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6}
/* 逆初始置换表IP^-1 */
int IP_1_Table[64] = {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,
32,0,40,8,48,16,56,24}
/* 扩充置换表慧液氏E */
int E_Table[48] = {31, 0, 1, 2, 3, 4,
3, 4, 5, 6, 7, 8,
7, 8,9,10,11,12,
11,12,13,14,15,16,
15,16,17,18,19,20,
19,20,21,22,23,24,
23,24,25,26,27,28,
27,28,29,30,31, 0}
/* 置换函数P */
int P_Table[32] = {15,6,19,20,28,11,27,16,
0,14,22,25,4,17,30,9,
1,7,23,13,31,26,2,8,
18,12,29,5,21,10,3,24}
/* S盒 */
int S[8][4][16] =/* 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}}}
/* 置换选择1 */
int PC_1[56] = {56,48,40,32,24,16,8,
0,57,49,41,33,25,17,
9,1,58,50,42,34,26,
18,10,2,59,51,43,35,
62,54,46,38,30,22,14,
6,61,53,45,37,29,21,
13,5,60,52,44,36,28,
20,12,4,27,19,11,3}
/* 置换选择2 */
int PC_2[48] = {13,16,10,23,0,4,2,27,
14,5,20,9,22,18,11,3,
25,7,15,6,26,19,12,1,
40,51,30,36,46,54,29,39,
50,44,32,46,43,48,38,55,
33,52,45,41,49,35,28,31}
/* 对左移次数的规定 */
int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}
int ByteToBit(ElemType ch,ElemType bit[8])
int BitToByte(ElemType bit[8],ElemType *ch)
int Char8ToBit64(ElemType ch[8],ElemType bit[64])
int Bit64ToChar8(ElemType bit[64],ElemType ch[8])
int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48])
int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56])
int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48])
int DES_ROL(ElemType data[56], int time)
int DES_IP_Transform(ElemType data[64])
int DES_IP_1_Transform(ElemType data[64])
int DES_E_Transform(ElemType data[48])
int DES_P_Transform(ElemType data[32])
int DES_SBOX(ElemType data[48])
int DES_XOR(ElemType R[48], ElemType L[48],int count)
int DES_Swap(ElemType left[32],ElemType right[32])
int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8])
int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8])
int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile)
int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile)
/* 字节转换成二进制 */
int ByteToBit(ElemType ch, ElemType bit[8]){
int cnt
for(cnt = 0cnt <8cnt++){
*(bit+cnt) = (ch>>cnt)&1
}
return 0
}
/* 二进制转换成字节 */
int BitToByte(ElemType bit[8],ElemType *ch){
int cnt
for(cnt = 0cnt <8cnt++){
*ch |= *(bit + cnt)<<cnt
}
return 0
}
/* 将长度为8的字符串转为二进制位串 */
int Char8ToBit64(ElemType ch[8],ElemType bit[64]){
int cnt
for(cnt = 0cnt <8cnt++){
ByteToBit(*(ch+cnt),bit+(cnt<<3))
}
return 0
}
/* 将二进制位串转为长度为8的字符串 */
int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){
int cnt
memset(ch,0,8)
for(cnt = 0cnt <8cnt++){
BitToByte(bit+(cnt<<3),ch+cnt)
}
return 0
}
/* 生成子密钥 */
int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){
ElemType temp[56]
int cnt
DES_PC1_Transform(key,temp)/* PC1置换 */
for(cnt = 0cnt <16cnt++){/* 16轮跌代,产生16个子密钥 */
DES_ROL(temp,MOVE_TIMES[cnt])/* 循环左移 */
DES_PC2_Transform(temp,subKeys[cnt])/* PC2置换,产生子密钥 */
}
return 0
}
/* 密钥置换1 */
int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]){
int cnt
for(cnt = 0cnt <56cnt++){
tempbts[cnt] = key[PC_1[cnt]]
}
return 0
}
/* 密钥置换2 */
int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]){
int cnt
for(cnt = 0cnt <48cnt++){
tempbts[cnt] = key[PC_2[cnt]]
}
return 0
}
/* 循环左移 */
int DES_ROL(ElemType data[56], int time){
ElemType temp[56]
/* 保存将要循环移动到右边的位 */
memcpy(temp,data,time)
memcpy(temp+time,data+28,time)
/* 前28位移动 */
memcpy(data,data+time,28-time)
memcpy(data+28-time,temp,time)
/* 后28位移动 */
memcpy(data+28,data+28+time,28-time)
memcpy(data+56-time,temp+time,time)
return 0
}
/* IP置换 */
int DES_IP_Transform(ElemType data[64]){
int cnt
ElemType temp[64]
for(cnt = 0cnt <64cnt++){
temp[cnt] = data[IP_Table[cnt]]
}
memcpy(data,temp,64)
return 0
}
/* IP逆置换 */
int DES_IP_1_Transform(ElemType data[64]){
int cnt
ElemType temp[64]
for(cnt = 0cnt <64cnt++){
temp[cnt] = data[IP_1_Table[cnt]]
}
memcpy(data,temp,64)
return 0
}
/* 扩展置换 */
int DES_E_Transform(ElemType data[48]){
int cnt
ElemType temp[48]
for(cnt = 0cnt <48cnt++){
temp[cnt] = data[E_Table[cnt]]
}
memcpy(data,temp,48)
return 0
}
/* P置换 */
int DES_P_Transform(ElemType data[32]){
int cnt
ElemType temp[32]
for(cnt = 0cnt <32cnt++){
temp[cnt] = data[P_Table[cnt]]
}
memcpy(data,temp,32)
return 0
}
/* 异或 */
int DES_XOR(ElemType R[48], ElemType L[48] ,int count){
int cnt
for(cnt = 0cnt <countcnt++){
R[cnt] ^= L[cnt]
}
return 0
}
/* S盒置换 */
int DES_SBOX(ElemType data[48]){
int cnt
int line,row,output
int cur1,cur2
for(cnt = 0cnt <8cnt++){
cur1 = cnt*6
cur2 = cnt<<2
/* 计算在S盒中的行与列 */
line = (data[cur1]<<1) + data[cur1+5]
row = (data[cur1+1]<<3) + (data[cur1+2]<<2)
+ (data[cur1+3]<<1) + data[cur1+4]
output = S[cnt][line][row]
/* 化为2进制 */
data[cur2] = (output&0X08)>>3
data[cur2+1] = (output&0X04)>>2
data[cur2+2] = (output&0X02)>>1
data[cur2+3] = output&0x01
}
return 0
}
/* 交换 */
int DES_Swap(ElemType left[32], ElemType right[32]){
ElemType temp[32]
memcpy(temp,left,32)
memcpy(left,right,32)
memcpy(right,temp,32)
return 0
}
/* 加密单个分组 */
int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]){
ElemType plainBits[64]
ElemType copyRight[48]
int cnt
Char8ToBit64(plainBlock,plainBits)
/* 初始置换(IP置换) */
DES_IP_Transform(plainBits)
/* 16轮迭代 */
for(cnt = 0cnt <16cnt++){
memcpy(copyRight,plainBits+32,32)
/* 将右半部分进行扩展置换,从32位扩展到48位 */
DES_E_Transform(copyRight)
/* 将右半部分与子密钥进行异或 *** 作 */
DES_XOR(copyRight,subKeys[cnt],48)
/* 异或结果进入S盒,输出32位结果 */
DES_SBOX(copyRight)
/* P置换 */
DES_P_Transform(copyRight)
/* 将明文左半部分与右半部分进行异或 */
DES_XOR(plainBits,copyRight,32)
if(cnt != 15){
/* 最终完成左右部的交换 */
DES_Swap(plainBits,plainBits+32)
}
}
/* 逆初始置换(IP^1置换) */
DES_IP_1_Transform(plainBits)
Bit64ToChar8(plainBits,cipherBlock)
return 0
}
/* 解密单个分组 */
int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8]){
ElemType cipherBits[64]
ElemType copyRight[48]
int cnt
Char8ToBit64(cipherBlock,cipherBits)
/* 初始置换(IP置换) */
DES_IP_Transform(cipherBits)
/* 16轮迭代 */
for(cnt = 15cnt >= 0cnt--){
memcpy(copyRight,cipherBits+32,32)
/* 将右半部分进行扩展置换,从32位扩展到48位 */
DES_E_Transform(copyRight)
/* 将右半部分与子密钥进行异或 *** 作 */
DES_XOR(copyRight,subKeys[cnt],48)
/* 异或结果进入S盒,输出32位结果 */
DES_SBOX(copyRight)
/* P置换 */
DES_P_Transform(copyRight)
/* 将明文左半部分与右半部分进行异或 */
DES_XOR(cipherBits,copyRight,32)
if(cnt != 0){
/* 最终完成左右部的交换 */
DES_Swap(cipherBits,cipherBits+32)
}
}
/* 逆初始置换(IP^1置换) */
DES_IP_1_Transform(cipherBits)
Bit64ToChar8(cipherBits,plainBlock)
return 0
}
/* 加密文件 */
int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){
FILE *plain,*cipher
int count
ElemType plainBlock[8],cipherBlock[8],keyBlock[8]
ElemType bKey[64]
ElemType subKeys[16][48]
if((plain = fopen(plainFile,"rb")) == NULL){
return PLAIN_FILE_OPEN_ERROR
}
if((cipher = fopen(cipherFile,"wb")) == NULL){
return CIPHER_FILE_OPEN_ERROR
}
/* 设置密钥 */
memcpy(keyBlock,keyStr,8)
/* 将密钥转换为二进制流 */
Char8ToBit64(keyBlock,bKey)
/* 生成子密钥 */
DES_MakeSubKeys(bKey,subKeys)
while(!feof(plain)){
/* 每次读8个字节,并返回成功读取的字节数 */
if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){
DES_EncryptBlock(plainBlock,subKeys,cipherBlock)
fwrite(cipherBlock,sizeof(char),8,cipher)
}
}
if(count){
/* 填充 */
memset(plainBlock + count,'\0',7 - count)
/* 最后一个字符保存包括最后一个字符在内的所填充的字符数量 */
plainBlock[7] = 8 - count
DES_EncryptBlock(plainBlock,subKeys,cipherBlock)
fwrite(cipherBlock,sizeof(char),8,cipher)
}
fclose(plain)
fclose(cipher)
return OK
}
/* 解密文件 */
int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){
FILE *plain, *cipher
int count,times = 0
long fileLen
ElemType plainBlock[8],cipherBlock[8],keyBlock[8]
ElemType bKey[64]
ElemType subKeys[16][48]
if((cipher = fopen(cipherFile,"rb")) == NULL){
return CIPHER_FILE_OPEN_ERROR
}
if((plain = fopen(plainFile,"wb")) == NULL){
return PLAIN_FILE_OPEN_ERROR
}
/* 设置密钥 */
memcpy(keyBlock,keyStr,8)
/* 将密钥转换为二进制流 */
Char8ToBit64(keyBlock,bKey)
/* 生成子密钥 */
DES_MakeSubKeys(bKey,subKeys)
/* 取文件长度 */
fseek(cipher,0,SEEK_END) /* 将文件指针置尾 */
fileLen = ftell(cipher) /* 取文件指针当前位置 */
rewind(cipher) /* 将文件指针重指向文件头 */
while(1){
/* 密文的字节数一定是8的整数倍 */
fread(cipherBlock,sizeof(char),8,cipher)
DES_DecryptBlock(cipherBlock,subKeys,plainBlock)
times += 8
if(times <fileLen){
fwrite(plainBlock,sizeof(char),8,plain)
}
else{
break
}
}
/* 判断末尾是否被填充 */
if(plainBlock[7] <8){
for(count = 8 - plainBlock[7]count <7count++){
if(plainBlock[count] != '\0'){
break
}
}
}
if(count == 7){/* 有填充 */
fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain)
}
else{/* 无填充 */
fwrite(plainBlock,sizeof(char),8,plain)
}
fclose(plain)
fclose(cipher)
return OK
}
int main()
{DES_Encrypt("1.txt","key.txt","2.txt")
system("pause")
DES_Decrypt("2.txt","key.txt","3.txt")
getchar()
return 0
}
#include <iostream>#include <fstream>
#include <bitset>
#include <string>
using namespace std
bitset<64> key
bitset<48> subKey[16]
int IP[] = {58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7}
int IP_1[] 档岩漏= {40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25}
int PC_1[] = {57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 行烂 4}
int PC_2[] = {14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 枣郑48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32}
int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
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}
int S_BOX[8][4][16] = {
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
},
{
{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}
}
}
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 }
bitset<32> f(bitset<32> R, bitset<48> k)
{
bitset<48> expandR
// 第一步:扩展置换,32 -> 48
for(int i=0 i<48 ++i)
expandR[47-i] = R[32-E[i]]
// 第二步:异或
expandR = expandR ^ k
// 第三步:查找S_BOX置换表
bitset<32> output
int x = 0
for(int i=0 i<48 i=i+6)
{
int row = expandR[47-i]*2 + expandR[47-i-5]
int col = expandR[47-i-1]*8 + expandR[47-i-2]*4 + expandR[47-i-3]*2 + expandR[47-i-4]
int num = S_BOX[i/6][row][col]
bitset<4> binary(num)
output[31-x] = binary[3]
output[31-x-1] = binary[2]
output[31-x-2] = binary[1]
output[31-x-3] = binary[0]
x += 4
}
// 第四步:P-置换,32 -> 32
bitset<32> tmp = output
for(int i=0 i<32 ++i)
output[31-i] = tmp[32-P[i]]
return output
}
bitset<28> leftShift(bitset<28> k, int shift)
{
bitset<28> tmp = k
for(int i=27 i>=0 --i)
{
if(i-shift<0)
k[i] = tmp[i-shift+28]
else
k[i] = tmp[i-shift]
}
return k
}
void generateKeys()
{
bitset<56> realKey
bitset<28> left
bitset<28> right
bitset<48> compressKey
// 去掉奇偶标记位,将64位密钥变成56位
for (int i=0 i<56 ++i)
realKey[55-i] = key[64 - PC_1[i]]
// 生成子密钥,保存在 subKeys[16] 中
for(int round=0 round<16 ++round)
{
// 前28位与后28位
for(int i=28 i<56 ++i)
left[i-28] = realKey[i]
for(int i=0 i<28 ++i)
right[i] = realKey[i]
// 左移
left = leftShift(left, shiftBits[round])
right = leftShift(right, shiftBits[round])
// 压缩置换,由56位得到48位子密钥
for(int i=28 i<56 ++i)
realKey[i] = left[i-28]
for(int i=0 i<28 ++i)
realKey[i] = right[i]
for(int i=0 i<48 ++i)
compressKey[47-i] = realKey[56 - PC_2[i]]
subKey[round] = compressKey
}
}
bitset<64> charToBitset(const char s[8])
{
bitset<64> bits
for(int i=0 i<8 ++i)
for(int j=0 j<8 ++j)
bits[i*8+j] = ((s[i]>>j) & 1)
return bits
}
bitset<64> encrypt(bitset<64>& plain)
{
bitset<64> cipher
bitset<64> currentBits
bitset<32> left
bitset<32> right
bitset<32> newLeft
// 第一步:初始置换IP
for(int i=0 i<64 ++i)
currentBits[63-i] = plain[64-IP[i]]
// 第二步:获取 Li 和 Ri
for(int i=32 i<64 ++i)
left[i-32] = currentBits[i]
for(int i=0 i<32 ++i)
right[i] = currentBits[i]
// 第三步:共16轮迭代
for(int round=0 round<16 ++round)
{
newLeft = right
right = left ^ f(right,subKey[round])
left = newLeft
}
// 第四步:合并L16和R16,注意合并为 R16L16
for(int i=0 i<32 ++i)
cipher[i] = left[i]
for(int i=32 i<64 ++i)
cipher[i] = right[i-32]
// 第五步:结尾置换IP-1
currentBits = cipher
for(int i=0 i<64 ++i)
cipher[63-i] = currentBits[64-IP_1[i]]
// 返回密文
return cipher
}
bitset<64> decrypt(bitset<64>& cipher)
{
bitset<64> plain
bitset<64> currentBits
bitset<32> left
bitset<32> right
bitset<32> newLeft
// 第一步:初始置换IP
for(int i=0 i<64 ++i)
currentBits[63-i] = cipher[64-IP[i]]
// 第二步:获取 Li 和 Ri
for(int i=32 i<64 ++i)
left[i-32] = currentBits[i]
for(int i=0 i<32 ++i)
right[i] = currentBits[i]
// 第三步:共16轮迭代(子密钥逆序应用)
for(int round=0 round<16 ++round)
{
newLeft = right
right = left ^ f(right,subKey[15-round])
left = newLeft
}
// 第四步:合并L16和R16,注意合并为 R16L16
for(int i=0 i<32 ++i)
plain[i] = left[i]
for(int i=32 i<64 ++i)
plain[i] = right[i-32]
// 第五步:结尾置换IP-1
currentBits = plain
for(int i=0 i<64 ++i)
plain[63-i] = currentBits[64-IP_1[i]]
// 返回明文
return plain
}
int main() {
string s = "romantic"
string k = "12345678"
bitset<64> plain = charToBitset(s.c_str())
key = charToBitset(k.c_str())
// 生成16个子密钥
generateKeys()
bitset<64> cipher = encrypt(plain)
fstream file1
file1.open("D://a.txt", ios::binary | ios::out)
file1.write((char*)&cipher,sizeof(cipher))
file1.close()
bitset<64> temp
file1.open("D://a.txt", ios::binary | ios::in)
file1.read((char*)&temp, sizeof(temp))
file1.close()
bitset<64> temp_plain = decrypt(temp)
file1.open("D://b.txt", ios::binary | ios::out)
file1.write((char*)&temp_plain,sizeof(temp_plain))
file1.close()
return 0
}
一.加密DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:
DES算法加密过程
对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:
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
该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将握咐薯在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:
f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2…… 一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。
R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:
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
经过置换IP-1后生成的比特串就是密文e.。
下面再讲一下变换f(Ri-1,Ki)。
它的功能是将32比特的输入再转化为32比特的输出。其过程如图所段者示:
对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表如下:
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 31
膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变简弯为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表如下:
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
经过P变换后输出的比特串才是32比特的f (Ri-1,Ki)。
下面再讲一下S盒的变换过程。任取一S盒。见图:
在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图所示)
至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:
for(i=1i<=64i++)
m1[i]=m[ip[i-1]]//64位明文串输入,经过IP置换。
下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。
for(i=1i<=48i++)//经过E变换扩充,由32位变为48位
RE1[i]=R7[E[i-1]]
for(i=1i<=48i++)//与K8按位作不进位加法运算
RE1[i]=RE1[i]+K8[i]
for(i=1i<=48i++)
{
if(RE1[i]==2)
RE1[i]=0
}
for(i=1i<7i++)//48位分成8组
{
s11[i]=RE1[i]
s21[i]=RE1[i+6]
s31[i]=RE1[i+12]
s41[i]=RE1[i+18]
s51[i]=RE1[i+24]
s61[i]=RE1[i+30]
s71[i]=RE1[i+36]
s81[i]=RE1[i+42]
}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表
s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8]
s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8]
s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8]
s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8]
s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8]
s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8]
s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8]
s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8]
for(i=0i<8i++)//8个数变换输出二进制
{
for(j=1j<5j++)
{
temp[j]=s[i+1]%2
s[i+1]=s[i+1]/2
}
for(j=1j<5j++)
f[4*i+j]=temp[5-j]
}
for(i=1i<33i++)//经过P变换
frk[i]=f[P[i-1]]//S盒运算完成
for(i=1i<33i++)//左右交换
L8[i]=R7[i]
for(i=1i<33i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果
{
R8[i]=L7[i]+frk[i]
if(R8[i]==2)
R8[i]=0
}
[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具
DES算法及其在VC++6.0下的实现(下)
作者:航天医学工程研究所四室 朱彦军
在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:
二.子密钥的生成
64比特的密钥生成16个48比特的子密钥。其生成过程见图:
子密钥生成过程具体解释如下:
64比特的密钥K,经过PC-1后,生成56比特的串。其下标如表所示:
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
该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:
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
C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。
注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:
迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
生成子密钥的VC程序源代码如下:
for(i=1i<57i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]]
56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1i<27i++)//循环左移两位
{
C8[i]=C7[i+2]
D8[i]=D7[i+2]
}
C8[27]=C7[1]
D8[27]=D7[1]
C8[28]=C7[2]
D8[28]=D7[2]
for(i=1i<=28i++)
{
C[i]=C8[i]
C[i+28]=D8[i]
}
for(i=1i<=48i++)
K8[i]=C[PC_2[i-1]]//生成子密钥k8
注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。
三.解密
DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。
第一圈:
加密后的结果
L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15
同理R15=L14⊕f(R14,K15), L15=R14。
同理类推:
得 L=R0, R=L0。
其程序源代码与加密相同。在此就不重写。
四.示例
例如:已知明文m=learning, 密钥 k=computer。
明文m的ASCII二进制表示:
m= 01101100 01100101 01100001 01110010
01101110 01101001 01101110 01100111
密钥k的ASCII二进制表示:
k=01100011 01101111 01101101 01110000
01110101 01110100 01100101 01110010
明文m经过IP置换后,得:
11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000
等分为左右两段:
L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000
经过16次迭代后,所得结果为:
L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101
L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111
L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100
L4=00111110101100010000101110000100 R4=11110111110101111111101000111110
L5=11110111110101111111101000111110 R5=10010110011001110100111111100101
L6=10010110011001110100111111100101 R6=11001011001010000101110110100111
L7=11001011001010000101110110100111 R7=01100011110011101000111011011001
L8=01100011110011101000111011011001 R8=01001011110100001111001000000100
L9=01001011110100001111001000000100 R9=00011101001101111010111011100001
L10=00011101001101111010111011100001 R10=11101110111110111111010100000101
L11=11101110111110111111010100000101 R11=01101101111011011110010111111000
L12=01101101111011011110010111111000 R12=11111101110011100111000110110111
L13=11111101110011100111000110110111 R13=11100111111001011010101000000100
L14=11100111111001011010101000000100 R14=00011110010010011011100001100001
L15=00011110010010011011100001100001 R15=01010000111001001101110110100011
L16=01010000111001001101110110100011 R16=01111101101010000100110001100001
其中,f函数的结果为:
f1=11001010001110011110100000000011 f2=00010111000111011100101101011111
f3=00001011100000000011000000100001 f4=11100000001101010100000010111001
f5=10101000110101100100010001100001 f6=00111100111111111010011110011001
f7=11110101101010011100000100111100 f8=10000000111110001010111110100011
f9=01111110111110010010000000111000 f10=10100101001010110000011100000001
f11=01110000110110100100101100011001 f12=00010011001101011000010010110010
f13=10001010000010000100111111111100 f14=11100011100001111100100111010110
f15=10110111000000010111011110100111 f16=01100011111000011111010000000000
16个子密钥为:
K1=11110000101111101110111011010000 K2=11100000101111101111011010010101
K3=11110100111111100111011000101000 K4=11100110111101110111001000011010
K5=11101110110101110111011100100110 K6=11101111110100110101101110001011
K7=00101111110100111111101111100110 K8=10111111010110011101101101010000
K9=00011111010110111101101101000100 K10=00111111011110011101110100001001
K11=00011111011011011100110101101000 K12=01011011011011011011110100001010
K13=11011101101011011010110110001111 K14=11010011101011101010111110000000
K15=11111001101111101010011011010011 K16=11110001101111100010111000000001
S盒中,16次运算时,每次的8 个结果为:
第一次:5,11,4,1,0,3,13,9;
第二次:7,13,15,8,12,12,13,1;
第三次:8,0,0,4,8,1,9,12;
第四次:0,7,4,1,7,6,12,4;
第五次:8,1,0,11,5,0,14,14;
第六次:14,12,13,2,7,15,14,10;
第七次:12,15,15,1,9,14,0,4;
第八次:15,8,8,3,2,3,14,5;
第九次:8,14,5,2,1,15,5,12;
第十次:2,8,13,1,9,2,10,2;
第十一次:10,15,8,2,1,12,12,3;
第十二次:5,4,4,0,14,10,7,4;
第十三次:2,13,10,9,2,4,3,13;
第十四次:13,7,14,9,15,0,1,3;
第十五次:3,1,15,5,11,9,11,4;
第十六次:12,3,4,6,9,3,3,0;
子密钥生成过程中,生成的数值为:
C0=0000000011111111111111111011 D0=1000001101110110000001101000
C1=0000000111111111111111110110 D1=0000011011101100000011010001
C2=0000001111111111111111101100 D2=0000110111011000000110100010
C3=0000111111111111111110110000 D3=0011011101100000011010001000
C4=0011111111111111111011000000 D4=1101110110000001101000100000
C5=1111111111111111101100000000 D5=0111011000000110100010000011
C6=1111111111111110110000000011 D6=1101100000011010001000001101
C7=1111111111111011000000001111 D7=0110000001101000100000110111
C8=1111111111101100000000111111 D8=1000000110100010000011011101
C9=1111111111011000000001111111 D9=0000001101000100000110111011
C10=1111111101100000000111111111 D10=0000110100010000011011101100
C11=1111110110000000011111111111 D11=0011010001000001101110110000
C12=1111011000000001111111111111 D12=1101000100000110111011000000
C13=1101100000000111111111111111 D13=0100010000011011101100000011
C14=0110000000011111111111111111 D14=0001000001101110110000001101
C15=1000000001111111111111111101 D15=0100000110111011000000110100
C16=0000000011111111111111111011 D16=1000001101110110000001101000
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)