首页 > 代码库 > S-DES加密
S-DES加密
1 #include <cstdio> 2 #include <iostream> 3 #include <fstream> 4 #include <algorithm> 5 #include <vector> 6 7 class S_DES { 8 private: 9 typedef unsigned int uint; 10 typedef unsigned char uchar; 11 typedef std::pair<unsigned int, unsigned int> PII; 12 typedef std::pair<PII, PII> PPI; 13 typedef std::vector<unsigned int> VI; 14 typedef std::vector<VI> VVI; 15 typedef std::vector<unsigned char> VC; 16 17 const static VI P_10; 18 const static VI P_8; 19 const static VI P_4; 20 const static VI IP; 21 const static VI IP_1; 22 const static VI EP; 23 const static VVI S_1; 24 const static VVI S_2; 25 26 // MakePII 27 inline PII MakePII(uint L, uint R) { 28 return std::make_pair(L, R); 29 } 30 31 // MakePPI 32 inline PPI MakePPI(uint A, uint B, uint C, uint D) { 33 return std::make_pair(std::make_pair(A, B), std::make_pair(C, D)); 34 } 35 36 // 置换,长度为X 37 int Permutation(uint Bit, int X, const VI &P) { 38 uint res = 0; 39 int n = P.size(); 40 for (int i = 0; i < n; i++) { 41 res <<= 1; 42 if (Bit & (1 << (X - P[i]))) res |= 1; 43 } 44 return res; 45 } 46 47 // 以X为单位分割二进制数为两份 48 PII Split(uint Bit, int X) { 49 uint L = 0, R = 0; 50 uint mask = (1 << X) - 1; 51 R = Bit & mask; 52 L = Bit >> X; 53 return MakePII(L, R); 54 } 55 56 // 将四位二进制数转化为S-BOX的坐标 57 PII GetBoxXY(uint Bit) { 58 uint x = 0, y = 0; 59 if (Bit&(1 << 3)) x |= 1; 60 if (Bit&(1 << 2)) y |= 1; 61 x <<= 1; 62 y <<= 1; 63 if (Bit&(1 << 0)) x |= 1; 64 if (Bit&(1 << 1)) y |= 1; 65 return MakePII(x, y); 66 } 67 68 // 将八位二进制数转化为S-BOX的坐标 69 PPI GetExBox(uint Bit) { 70 PII pii = Split(Bit,4); 71 PII xy1 = GetBoxXY(pii.first); 72 PII xy2 = GetBoxXY(pii.second); 73 return MakePPI(xy1.first, xy1.second, xy2.first, xy2.second); 74 } 75 76 // 合并两个长度为X的二进制数 77 uint Merge(uint lBit, uint rBit, int X) { 78 return (lBit << X) | rBit; 79 } 80 81 // 将长度为L的二进制数,循环左移X次 82 uint LS(uint Bit, int L, int X) { 83 X %= L; 84 uint mask = (1 << L) - 1; 85 uint ans = ((Bit << X) & mask) | (Bit >> (L - X)); 86 return ans; 87 } 88 89 // S-DES 子密码生成过程,MasterKey是10位的主密钥。 90 PII GetSubPsw(uint MasterKey) { 91 uint K = Permutation(MasterKey, 10, P_10);// 主密钥K进行P10置换 92 PII pii = Split(K, 5); // 分成左5位右5位 93 uint L = pii.first; // 94 uint R = pii.second; // 95 L = LS(L, 5, 1); // 分别进行LS-1操作 96 R = LS(R, 5, 1); // 其结果一方面作为下一轮的初始值 97 uint K_1 = Merge(L, R, 5); // 另一方面进行P8置换 98 K_1 = Permutation(K_1, 10, P_8); // 得到K1 99 L = LS(L, 5, 2); // 再分别左循环2位100 R = LS(R, 5, 2); // 101 uint K_2 = Merge(L, R, 5); // 102 K_2 = Permutation(K_2, 10, P_8); // 经过P8置换,得到K2103 return MakePII(K_1, K_2);104 }105 106 // S-DES的f函数107 uint Function(uint Ipt, uint K) {108 uint ex = Permutation(Ipt, 4, EP);// E/P扩展及置换。将4位R扩展为8位109 ex ^= K; // 扩展后的8位异或秘钥K110 PPI ppi = GetExBox(ex); // 左边4位作为S1盒输入,右边四位作为S2盒输入111 uint x1 = ppi.first.first; // 在S1和S2中,第一位与第四位结合形成2位代表S盒的行号112 uint y1 = ppi.first.second; // 第二位与第三位结合形成2位代表S盒的列号113 uint x2 = ppi.second.first; //114 uint y2 = ppi.second.second; //115 uint s1 = S_1[x1][y1]; // 得到S盒的输出116 uint s2 = S_2[x2][y2]; //117 uint res = Merge(s1, s2, 2); //118 res = Permutation(res, 4, P_4); // 进行P4置换,得到f函数的输出119 return res;120 }121 122 // S-DES 加密123 uint S_DES_Main(uint Plaintext, uint K_1, uint K_2) {124 Plaintext = Permutation(Plaintext, 8, IP);// 初始置换IP,将8位明文按照置换顺序进行位置变化。125 PII pii = Split(Plaintext, 4); // 置换后分126 uint L0 = pii.first; // 左4位L0127 uint R0 = pii.second; // 右4位R0128 uint L1 = R0; // 第一轮运算,R0作为下一轮的L1129 uint R1 = L0 ^ (Function(R0, K_1)); // R0作为f函数的输入与8位子秘钥K1参与函数运算,运算结构与L0异或,结果作为下一轮的R1130 uint R2 = R1; // 第二轮运算,R1作为下一轮的R2131 uint L2 = L1 ^ (Function(R1, K_2)); // R1作为f函数的输入与8位子密钥K2参与函数运算,运算结果与L1异或,结果作为下一轮的L2132 uint res = Merge(L2, R2, 4); // 133 res = Permutation(res, 8, IP_1); // 逆置换IP-1134 return res;135 }136 public:137 // 将数字以二进制形式输出138 void PrintBinary(uint b) {139 if (b == 0) {140 printf("0\n");141 return;142 }143 VI vec;144 vec.clear();145 while (b > 0) {146 if (b & 1) vec.push_back(1);147 else vec.push_back(0);148 b >>= 1;149 }150 for (auto it = vec.rbegin(); it != vec.rend(); it++) {151 printf("%d", *it);152 }153 printf("\n");154 }155 156 // 将二进制字符串转换为数字157 uint StringToBinary(const std::string &Str) {158 uint res = 0;159 uint len = Str.length();160 for (uint i = 0; i < len; i++) {161 res <<= 1;162 if (Str[i] == ‘1‘) res |= 1;163 }164 return res;165 }166 167 // 加密一个单位的数据168 uint EncryptInt(uint Text, uint MasterKey) {169 auto p = GetSubPsw(MasterKey);170 uint K_1 = p.first;171 uint K_2 = p.second;172 uint res = S_DES_Main(Text, K_1, K_2);173 return res;174 }175 176 // 按字符加密一个字符串177 VI EncryptString(const std::string &Str, uint MasterKey) {178 VI res;179 auto p = GetSubPsw(MasterKey);180 uint K_1 = p.first;181 uint K_2 = p.second;182 int len = Str.length();183 for (int i = 0; i < len; i++) {184 uint e = S_DES_Main((uint)Str[i], K_1, K_2);185 res.push_back(e);186 }187 return res;188 }189 190 // 加密一组vector中的数字191 VI EncryptVector(const VI &Arr, uint MasterKey) {192 VI res;193 auto p = GetSubPsw(MasterKey);194 uint K_1 = p.first;195 uint K_2 = p.second;196 int len = Arr.size();197 for (int i = 0; i < len; i++) {198 uint e = S_DES_Main(Arr[i], K_1, K_2);199 res.push_back(e);200 }201 return res;202 }203 204 // 加密长度为n的数组中的数字205 VI EncryptArray(const uint Arr[], int n, uint MasterKey) {206 VI res;207 auto p = GetSubPsw(MasterKey);208 uint K_1 = p.first;209 uint K_2 = p.second;210 for (int i = 0; i < n; i++) {211 uint e = S_DES_Main(Arr[i], K_1, K_2);212 res.push_back(e);213 }214 return res;215 }216 217 // 加密一个文件中的数据218 VI EncryptFile(char FileName[], uint MasterKey) {219 VI res;220 std::ifstream fin(FileName, std::ios::binary);221 if (!fin.is_open()) return res;222 int n = (int)fin.gcount(); 223 uint bit = 0;224 for (int i = 0; i < n; i++) {225 char pc;226 fin.read(&pc, sizeof(uchar));227 bit <<= 8;228 bit |= pc;229 if (i & 1) {230 bit = EncryptInt(bit, MasterKey);231 res.push_back(bit);232 bit = 0;233 }234 }235 if (n & 1) {236 bit <<= 8;237 bit = EncryptInt(bit, MasterKey);238 res.push_back(bit);239 }240 return res;241 }242 243 244 };245 246 const S_DES::VI S_DES::P_10{ 3, 5, 2, 7, 4, 10, 1, 9, 8, 6 };247 const S_DES::VI S_DES::P_8{ 6, 3, 7, 4, 8, 5, 10, 9 };248 const S_DES::VI S_DES::P_4{ 2, 4, 3, 1 };249 const S_DES::VI S_DES::IP{ 2, 6, 3, 1, 4, 8, 5, 7 };250 const S_DES::VI S_DES::IP_1{ 4, 1, 3, 5, 7, 2, 8, 6 };251 const S_DES::VI S_DES::EP{ 4, 1, 2, 3, 2, 3, 4, 1 };252 const S_DES::VVI S_DES::S_1{ { 1, 0, 3, 2 },253 { 3, 2, 1, 0 },254 { 0, 2, 1, 3 },255 { 3, 1, 3, 2 } };256 const S_DES::VVI S_DES::S_2{ { 0, 1, 2, 3 },257 { 2, 0, 1, 3 }, 258 { 3, 0, 1, 0 },259 { 2, 1, 0, 3 } };
S-DES加密
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。