Advertisement
Guest User

Untitled

a guest
Jul 24th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.76 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <bitset>
  4. #include <string>
  5. using namespace std;
  6.  
  7. bitset<64> key; // 64位密钥
  8. bitset<48> subKey[16]; // 存放16轮子密钥
  9.  
  10. // 初始置换表
  11. int IP[] = {58, 50, 42, 34, 26, 18, 10, 2,
  12. 60, 52, 44, 36, 28, 20, 12, 4,
  13. 62, 54, 46, 38, 30, 22, 14, 6,
  14. 64, 56, 48, 40, 32, 24, 16, 8,
  15. 57, 49, 41, 33, 25, 17, 9, 1,
  16. 59, 51, 43, 35, 27, 19, 11, 3,
  17. 61, 53, 45, 37, 29, 21, 13, 5,
  18. 63, 55, 47, 39, 31, 23, 15, 7};
  19.  
  20. // 结尾置换表
  21. int IP_1[] = {40, 8, 48, 16, 56, 24, 64, 32,
  22. 39, 7, 47, 15, 55, 23, 63, 31,
  23. 38, 6, 46, 14, 54, 22, 62, 30,
  24. 37, 5, 45, 13, 53, 21, 61, 29,
  25. 36, 4, 44, 12, 52, 20, 60, 28,
  26. 35, 3, 43, 11, 51, 19, 59, 27,
  27. 34, 2, 42, 10, 50, 18, 58, 26,
  28. 33, 1, 41, 9, 49, 17, 57, 25};
  29.  
  30. /*------------------下面是生成密钥所用表-----------------*/
  31.  
  32. // 密钥置换表,将64位密钥变成56位
  33. int PC_1[] = {57, 49, 41, 33, 25, 17, 9,
  34. 1, 58, 50, 42, 34, 26, 18,
  35. 10, 2, 59, 51, 43, 35, 27,
  36. 19, 11, 3, 60, 52, 44, 36,
  37. 63, 55, 47, 39, 31, 23, 15,
  38. 7, 62, 54, 46, 38, 30, 22,
  39. 14, 6, 61, 53, 45, 37, 29,
  40. 21, 13, 5, 28, 20, 12, 4};
  41.  
  42. // 压缩置换,将56位密钥压缩成48位子密钥
  43. int PC_2[] = {14, 17, 11, 24, 1, 5,
  44. 3, 28, 15, 6, 21, 10,
  45. 23, 19, 12, 4, 26, 8,
  46. 16, 7, 27, 20, 13, 2,
  47. 41, 52, 31, 37, 47, 55,
  48. 30, 40, 51, 45, 33, 48,
  49. 44, 49, 39, 56, 34, 53,
  50. 46, 42, 50, 36, 29, 32};
  51.  
  52. // 每轮左移的位数
  53. int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
  54.  
  55. /*------------------下面是密码函数 f 所用表-----------------*/
  56.  
  57. // 扩展置换表,将 32位 扩展至 48位
  58. int E[] = {32, 1, 2, 3, 4, 5,
  59. 4, 5, 6, 7, 8, 9,
  60. 8, 9, 10, 11, 12, 13,
  61. 12, 13, 14, 15, 16, 17,
  62. 16, 17, 18, 19, 20, 21,
  63. 20, 21, 22, 23, 24, 25,
  64. 24, 25, 26, 27, 28, 29,
  65. 28, 29, 30, 31, 32, 1};
  66.  
  67. // S盒,每个S盒是4x16的置换表,6位 -> 4位
  68. int S_BOX[8][4][16] = {
  69. {
  70. {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},
  71. {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},
  72. {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},
  73. {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}
  74. },
  75. {
  76. {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},
  77. {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
  78. {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},
  79. {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}
  80. },
  81. {
  82. {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},
  83. {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
  84. {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},
  85. {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}
  86. },
  87. {
  88. {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},
  89. {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
  90. {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},
  91. {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}
  92. },
  93. {
  94. {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
  95. {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},
  96. {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
  97. {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}
  98. },
  99. {
  100. {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
  101. {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},
  102. {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
  103. {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}
  104. },
  105. {
  106. {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
  107. {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},
  108. {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
  109. {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}
  110. },
  111. {
  112. {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
  113. {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},
  114. {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
  115. {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}
  116. }
  117. };
  118.  
  119. // P置换,32位 -> 32位
  120. int P[] = {16, 7, 20, 21,
  121. 29, 12, 28, 17,
  122. 1, 15, 23, 26,
  123. 5, 18, 31, 10,
  124. 2, 8, 24, 14,
  125. 32, 27, 3, 9,
  126. 19, 13, 30, 6,
  127. 22, 11, 4, 25 };
  128.  
  129. /**********************************************************************/
  130. /* */
  131. /* 下面是DES算法实现 */
  132. /* */
  133. /**********************************************************************/
  134.  
  135. /**
  136. * 密码函数f,接收32位数据和48位子密钥,产生一个32位的输出
  137. */
  138. bitset<32> f(bitset<32> R, bitset<48> k)
  139. {
  140. bitset<48> expandR;
  141. // 第一步:扩展置换,32 -> 48
  142. for(int i=0; i<48; ++i)
  143. expandR[47-i] = R[32-E[i]];
  144. // 第二步:异或
  145. expandR = expandR ^ k;
  146. // 第三步:查找S_BOX置换表
  147. bitset<32> output;
  148. int x = 0;
  149. for(int i=0; i<48; i=i+6)
  150. {
  151. int row = expandR[47-i]*2 + expandR[47-i-5];
  152. int col = expandR[47-i-1]*8 + expandR[47-i-2]*4 + expandR[47-i-3]*2 + expandR[47-i-4];
  153. int num = S_BOX[i/6][row][col];
  154. bitset<4> binary(num);
  155. output[31-x] = binary[3];
  156. output[31-x-1] = binary[2];
  157. output[31-x-2] = binary[1];
  158. output[31-x-3] = binary[0];
  159. x += 4;
  160. }
  161. // 第四步:P-置换,32 -> 32
  162. bitset<32> tmp = output;
  163. for(int i=0; i<32; ++i)
  164. output[31-i] = tmp[32-P[i]];
  165. return output;
  166. }
  167.  
  168. /**
  169. * 对56位密钥的前后部分进行左移
  170. */
  171. bitset<28> leftShift(bitset<28> k, int shift)
  172. {
  173. bitset<28> tmp = k;
  174. for(int i=27; i>=0; --i)
  175. {
  176. if(i-shift<0)
  177. k[i] = tmp[i-shift+28];
  178. else
  179. k[i] = tmp[i-shift];
  180. }
  181. return k;
  182. }
  183.  
  184. /**
  185. * 生成16个48位的子密钥
  186. */
  187. void generateKeys()
  188. {
  189. bitset<56> realKey;
  190. bitset<28> left;
  191. bitset<28> right;
  192. bitset<48> compressKey;
  193. // 去掉奇偶标记位,将64位密钥变成56位
  194. for (int i=0; i<56; ++i)
  195. realKey[55-i] = key[64 - PC_1[i]];
  196. // 生成子密钥,保存在 subKeys[16] 中
  197. for(int round=0; round<16; ++round)
  198. {
  199. // 前28位与后28位
  200. for(int i=28; i<56; ++i)
  201. left[i-28] = realKey[i];
  202. for(int i=0; i<28; ++i)
  203. right[i] = realKey[i];
  204. // 左移
  205. left = leftShift(left, shiftBits[round]);
  206. right = leftShift(right, shiftBits[round]);
  207. // 压缩置换,由56位得到48位子密钥
  208. for(int i=28; i<56; ++i)
  209. realKey[i] = left[i-28];
  210. for(int i=0; i<28; ++i)
  211. realKey[i] = right[i];
  212. for(int i=0; i<48; ++i)
  213. compressKey[47-i] = realKey[56 - PC_2[i]];
  214. subKey[round] = compressKey;
  215. }
  216. }
  217.  
  218. /**
  219. * 工具函数:将char字符数组转为二进制
  220. */
  221. bitset<64> charToBitset(const char s[8])
  222. {
  223. bitset<64> bits;
  224. for(int i=0; i<8; ++i)
  225. for(int j=0; j<8; ++j)
  226. bits[i*8+j] = ((s[i]>>j) & 1);
  227. return bits;
  228. }
  229.  
  230. template<size_t len>
  231. string Bitset2String(const bitset<len> & bits)
  232. {
  233. if(len%8)
  234. return "";
  235. string s;
  236. for(int i=0;i<64/8;++i){
  237. char var=0;
  238. for(int j=0;j<8;++j){
  239. var=var|(bits[i*8+j]<<j);
  240. }
  241. s.push_back(var);
  242. }
  243. return s;
  244. }
  245.  
  246. /*
  247. * flag 为真为加密,为假为解密
  248. */
  249. bitset<64> des(bitset<64>& cipher,bool flag)
  250. {
  251. bitset<64> plain;
  252. bitset<64> currentBits;
  253. bitset<32> left;
  254. bitset<32> right;
  255. bitset<32> newLeft;
  256. // 第一步:初始置换IP
  257. for(int i=0; i<64; ++i)
  258. currentBits[63-i] = cipher[64-IP[i]];
  259. // 第二步:获取 Li 和 Ri
  260. for(int i=32; i<64; ++i)
  261. left[i-32] = currentBits[i];
  262. for(int i=0; i<32; ++i)
  263. right[i] = currentBits[i];
  264. // 第三步:共16轮迭代
  265. for(int round=0; round<16; ++round)
  266. {
  267. newLeft = right;
  268. right = left ^ f(right,flag?subKey[round]:subKey[15-round]);
  269. left = newLeft;
  270. }
  271. // 第四步:合并L16和R16,注意合并为 R16L16
  272. for(int i=0; i<32; ++i)
  273. plain[i] = left[i];
  274. for(int i=32; i<64; ++i)
  275. plain[i] = right[i-32];
  276. // 第五步:结尾置换IP-1
  277. currentBits = plain;
  278. for(int i=0; i<64; ++i)
  279. plain[63-i] = currentBits[64-IP_1[i]];
  280. // 返回明文
  281. return plain;
  282. }
  283.  
  284.  
  285.  
  286.  
  287. int main()
  288. {
  289. string s = "romantic";
  290. string k = "12345678";
  291. bitset<64> plain = charToBitset(s.c_str());
  292. key = charToBitset(k.c_str());
  293. // 生成16个子密钥
  294. generateKeys();
  295. //加密
  296. bitset<64> cipher = des(plain,true);
  297. string my=Bitset2String(cipher);
  298. cout<<my<<endl;
  299. //解密
  300. bitset<64> temp_plain = des(cipher,false);
  301. string my_plain=Bitset2String(temp_plain);
  302. cout<<my_plain<<endl;
  303. return 0;
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement