大整数加减乘除取模,非负数运算可以保证正确率,负数运算不保证准确率,乘法没有使用快速傅里叶变换加速,自从学了 \(FFT\) 之后感觉实现较难,所以没有花精力嵌入大整数模板,属于低级轮子
#include <bits/stdc++.h>
using namespace std;
int cmp(string A, string B);
string operator + (const string& a, const string& b);
string operator - (const string& a, const string& b);
string operator * (const string& a, const string& b);
string operator / (const string& a, const string& b);
string operator % (const string& a, const string& b);
int main()
{
freopen("in.txt", "r", stdin);
string s1, s2, s3, s4, s5, s6, s7;
int f = 0;
while (cin >> s1 >> s2 >> s3 >> s4 >> s5 >> s6 >> s7) {
int f[5] = {0};
if (s1 + s2 == s3) f[0] = 1;
if (s1 - s2 == s4) f[1] = 1;
if (s1 * s2 == s5) f[2] = 1;
if (s1 / s2 == s6) f[3] = 1;
if (s1 % s2 == s7) f[4] = 1;
for (int i = 0; i < 5; ++i) {
if (f[i] == 0) cout << "×";
else cout << "√";
}
cout << endl;
}
//puts(!f ? "AC" : "WA");
return 0;
}
int cmp(string A, string B)
{
if (A.length() < B.length()) return -1;
else if (A.length() > B.length()) return 1;
else {
for (int i = 0; i < A.length(); ++i) {
if (A[i] < B[i]) return -1;
else if (A[i] > B[i]) return 1;
}
return 0;
}
}
string operator + (const string& a, const string& b)
{
int flag = 0;
if (a[0] == ‘-‘ && b[0] == ‘-‘) flag = 1; // (-a) + (-b) = -(a + b)
else if (a[0] == ‘-‘ && b[0] != ‘-‘) return b - a.substr(1, a.length()); // -a + b = b - a
else if (a[0] != ‘-‘ && b[0] == ‘-‘) return a - b.substr(1, b.length()); // a + (-b) = a - b
else flag = 0; // a + b
string A = "", B = "";
A = flag ? a.substr(1, a.length()) : a;
B = flag ? b.substr(1, b.length()) : b;
reverse(A.begin(), A.end());
reverse(B.begin(), B.end());
if (A.length() < B.length()) swap(A, B);
int L1 = A.length(), L2 = B.length();
string C = "";
int now = 0, up = 0;
for (int i = 0; i < L1; ++i) {
if (i < L2) now = up + A[i] - ‘0‘ + B[i] -‘0‘;
else now = up + A[i] - ‘0‘;
up = now / 10;
now %= 10;
C += now + ‘0‘;
}
while (up) C += up % 10 + ‘0‘, up /= 10;
if (flag) C += ‘-‘;
reverse(C.begin(), C.end());
return C;
}
string operator - (const string& a, const string& b)
{
string A = "";
string B = "";
if (a[0] == ‘-‘ && b[0] == ‘-‘) { // -a - (-b) = b - a
A = a.substr(1, a.length());
B = b.substr(1, b.length());
return B - A;
}
else if (a[0] == ‘-‘ && b[0] != ‘-‘) { // -a - b = (-a) + (-b)
A = a;
B = b;
return (A + B).insert(0, "-");
}
else if (a[0] != ‘-‘ && b[0] == ‘-‘) { // a - (-b) = a + b
A = a;
B = b.substr(1, b.length());
return A + B;
}
else { // a - b
A = a, B = b;
int flag = 0;
if (cmp(A, B) == -1) swap(A, B), flag = 1;
reverse(A.begin(), A.end());
reverse(B.begin(), B.end());
int L1 = A.length(), L2 = B.length();
int now = 0, lend = 0;
string C = "";
for (int i = 0; i < L1; ++i) {
if (i < L2) now = lend + (A[i] - ‘0‘) - (B[i] - ‘0‘);
else now = lend + (A[i] - ‘0‘);
if (now < 0) now += 10, lend = -1;
else lend = 0;
C += now + ‘0‘;
}
int pos = C.length() - 1;
while (C[pos] == ‘0‘ && pos > 0) --pos;
C = C.substr(0, pos + 1);
if (flag) C += ‘-‘;
reverse(C.begin(), C.end());
return C;
}
}
string operator * (const string& a, const string& b)
{
int flag = 0;
if (a[0] == ‘-‘ && b[0] == ‘-‘) flag = 0;
else if (a[0] == ‘-‘ && b[0] != ‘-‘) flag = 1;
else if (a[0] != ‘-‘ && b[0] == ‘-‘) flag = 1;
else flag = 0;
string A = a[0] == ‘-‘ ? a.substr(1, a.length()) : a;
string B = b[0] == ‘-‘ ? b.substr(1, b.length()) : b;
reverse(A.begin(), A.end());
reverse(B.begin(), B.end());
if (A.length() < B.length()) swap(A, B);
int L1 = A.length(), L2 = B.length();
vector<int> arr(L1 + L2, 0);
for (int i = 0; i < L1; ++i)
for (int j = 0; j < L2; ++j)
arr[i + j] += (A[i] - ‘0‘) * (B[j] - ‘0‘);
string C = "";
int up = 0;
for (int i = 0; i < L1 + L2; ++i) {
int now = up + arr[i];
C += now % 10 + ‘0‘;
up = now / 10;
}
while (up) {
C += up % 10;
up = up / 10;
}
int pos = C.length() - 1;
while (C[pos] == ‘0‘ && pos > 0) --pos;
C = C.substr(0, pos + 1);
if (flag) C += ‘-‘;
reverse(C.begin(), C.end());
return C;
}
string operator / (const string& a, const string& b)
{
string A = a;
string B = b;
if (B == "0") return "false";
if (cmp(A, B) < 0) return "0";
else if (cmp(A, B) == 0) return "1";
else {
int L1 = A.length(), L2 = B.length();
string C = "";
string temp = "0";
for (int i = 0; i < L1; ++i) {
string x = string(1, A[i]);
temp = temp + x;
int cnt = 0;
while (cmp(temp, B) >= 0) temp = temp - B, cnt++;
temp = temp * "10";
C += cnt + ‘0‘;
}
int pos = 0;
while (C[pos] == ‘0‘) pos++;
return C.substr(pos, C.length() - pos + 1);
}
}
string operator % (const string& a, const string& b)
{
if (b == "0") return "false";
return a - a / b * b;
}
代码生成 \(10\) 个 120-bit
大素数并输出运行时间,使用 __int128
来代替大整数
#include <bits/stdc++.h>
#define int128 __int128
using namespace std;
string genRandString(int L)
{
string ans = "";
ans += ‘1‘;
for (int i = 0; i < L - 2; ++i) ans += ‘0‘ + rand() % 2;
ans += ‘1‘;
return ans;
}
int128 stringToInt(string s)
{
int128 ans = 0;
for (int i = 0; i < s.length(); ++i) ans *= 2, ans += s[i] - ‘0‘;
return ans;
}
string intToString(int128 n)
{
string s1 = "", s2 = "";
while (n) {
s1 += n % 10 + ‘0‘;
n /= 10;
}
for(int i = s1.length() - 1; i >= 0; --i) s2 += s1[i];
return s2;
}
int128 randInt128(int128 a, int128 b)
{
mt19937 eng(time(0));
uniform_int_distribution<int128> dis(a, b);
return dis(eng);
}
int128 qmul(int128 a, int128 b, int128 p)
{
int128 ans = 0;
while (b) {
if (b & 1) ans += a, ans %= p;
a += a, a %= p, b >>= 1;
}
return ans;
}
int128 qpow(int128 a, int128 b, int128 p)
{
int128 ans = 1;
while (b) {
if (b & 1) ans = qmul(ans, a, p);
a = qmul(a, a, p), b >>= 1;
}
return ans;
}
bool miller_rabin(int128 n, int k)
{
int128 t = n - 1;
int s = 0;
while (t % 2 == 0) t /= 2, s++;
for (int i = 0; i < k; ++i) {
int128 a = randInt128(2, n - 2); // 生成 [2, n-2] 中的随机数 a
//cout << intToString(a) << endl;
int128 temp = qpow(a, t, n);
if (temp % n == 1 || temp % n == n - 1) continue; // 本轮检测通过
int flag = 0;
for (int j = 1; j < s; ++j) {
temp = qmul(temp, temp, n);
if (temp % n == n - 1) {flag = 1; break;}
}
if (flag) continue; // 本轮检测通过
return 0; // 检测不通过
}
return 1;
}
bool isPrime(int128 n)
{
if (n == 1) return 0; // 判断 1
if (n == 2) return 1; // 判断 2
if (n % 2 == 0) return 0; // 判断偶数
int k = 10;
return miller_rabin(n, k);
}
void solve()
{
auto s = clock();
srand((unsigned)time(0));
int L = 120;
int cnt = 0;
while (cnt <= 10) {
string s = genRandString(L);
int128 n = stringToInt(s);
string N = intToString(n);
//cout << s << endl;
//cout << N << endl;
int flag = isPrime(n);
//puts(flag == 1 ? "Prime" : "Not prime");
if (flag == 1) {
cout << N << endl;
cnt++;
}
}
auto t = clock();
cout << (double)(t - s) / CLOCKS_PER_SEC << endl;
}
int main()
{
solve();
return 0;
}
递推出循环节之后分组异或加密
#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
using namespace std;
int dp[15];
void init()
{
dp[0] = 0, dp[1] = 0, dp[2] = 0, dp[3] = 1;
for (int i = 4; i < 15; ++i)
dp[i] = (dp[i - 1] + dp[i - 4]) % 2;
}
string input(string msg)
{
string ans = "";
for (int i = 0; i < msg.length(); ++i) {
char x = msg[i];
//cout << x << endl;
string temp = "";
while (x) {
temp += x % 2 + ‘0‘;
x /= 2;
}
for (int i = temp.length(); i < 8; ++i) temp += ‘0‘;
reverse(temp.begin(), temp.end());
ans += temp;
}
return ans;
}
pair<string, string> encry(string msg)
{
int L = msg.length();
int x = L / 15, y = L % 15;
string key = "";
for (int i = 1; i <= x; ++i)
for (int j = 0; j < 15; ++j)
key += dp[j] + ‘0‘;
for (int i = 0; i < y; ++i)
key += dp[i] + ‘0‘;
string cipher = "";
for (int i = 0; i < L; ++i)
cipher += ‘0‘ + (msg[i] - ‘0‘) ^ (key[i] - ‘0‘);
return {cipher, key};
}
string decry(string c, string k)
{
string temp = "";
int L = c.length();
for (int i = 0; i < L; ++i)
temp += ‘0‘ + (c[i] - ‘0‘) ^ (k[i] - ‘0‘);
int res = temp[0] - ‘0‘;
string ans = "";
for (int i = 1; i <= L; ++i) {
if (i % 8 == 0) ans += char(res), res = temp[i] - ‘0‘;
else res = res * 2 + temp[i] - ‘0‘;
}
return ans;
}
int main()
{
init();
cout << "Please input the cipher text" << endl;
string s;
getline(cin, s);
string msg = input(s);
pair<string, string> pss = encry(msg);
string cipher = pss.first;
string key = pss.second;
cout << "The cipher text is:\n" << cipher << endl;
cout << "The key is:\n" << key << endl;
string plain = decry(cipher, key);
cout << "The decrypted plain text is:\n" << plain << endl;
return 0;
}
/*
000111101011001
000101001101110
*/
\(DES\) 加密分为密钥生成,与明文加密,夹杂一系列混淆扩散操作,解密与加密完全一样,只不过密钥的使用顺序反过来
输入明文和密钥,输出密文,并输出解密后的明文
输入的均为 64-bit
的二进制串,输出的均为 16
进制数
#include <bits/stdc++.h>
using namespace std;
// 初始置换表,置换 64 位明文
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};
// 密钥置换表,将 64 位密钥变成 56 位
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};
// 压缩置换,将 56 位密钥压缩成 48 位子密钥
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};
// 扩展置换表,将 bitset<32> 扩展至 bitset<48>
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};
// S盒,每个S盒是4x16的置换表,6位 -> 4位
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}
}
};
// P置换,32位 -> 32位
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};
// 尾置换表
int IP_inverse[] = {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};
/* 重载 bitset<28> 的加法运算符 */
bitset<56> operator+(const bitset<28> &bt1, const bitset<28> &bt2)
{
string s1 = bt1.to_string(), s2 = bt2.to_string();
s1 += s2;
return bitset<56>(s1);
}
/* 重载 bitset<32> 的加法运算符 */
bitset<64> operator+(const bitset<32> &bt1, const bitset<32> &bt2)
{
string s1 = bt1.to_string(), s2 = bt2.to_string();
s1 += s2;
return bitset<64>(s1);
}
/* 鉴于 bitset 实际下标从低位(从右往左)算起,因此对逻辑下标(从左往右)做一个转换,下标从零开始计数 */
/* input: bitset 的长度 n,逻辑下标 pos */
/* output: 实际下标 */
int TransIndex(int n, int pos)
{
return n - pos - 1;
}
/* 利用 IP 对输入的 bitset<64> input 进行初始置换 */
/* input: 初始明文 input */
/* output: 置换后的两个 bitset<32> 明文组成的 vector */
vector<bitset<32>> InitialPermutation(const bitset<64> &input)
{
string str = "";
for (int i = 0; i < 64; ++i)
str += input[TransIndex(64, IP[i] - 1)] + ‘0‘;
string substr1 = str.substr(0, 32);
string substr2 = str.substr(32, 32);
vector<bitset<32>> ret;
ret.emplace_back(bitset<32>(substr1));
ret.emplace_back(bitset<32>(substr2));
return ret;
}
/* 利用 PC_1 对输入的 bitset<64> key 进行密钥置换 */
/* input: 密钥 key */
/* output: 置换压缩后的 key */
bitset<56> KeyPermutation(const bitset<64> &key)
{
string str = "";
for (int i = 0; i < 56; ++i)
str += key[TransIndex(64, PC_1[i] - 1)] + ‘0‘;
return bitset<56>(str);
}
/* 对 bitset<28> 的密钥进行循环左移 */
/* input: bitset<28> key, 左移轮数 round */
/* output: 左移后的 bitset<28> */
bitset<28> LeftShift(const bitset<28> &key, int round)
{
int shift = shiftBits[round];
return ((key << shift) | (key >> (28 - shift)));
}
/* 先将输入的 bitset<28> key1, key2 进行拼接,再利用 PC_2 对输入的 bitset<56> 进行密钥压缩 */
/* key1, key2 可修改 */
/* input: 两个子密钥 bitset<28> key1, key2,左移轮数 round */
/* output: 合成压缩后的长度为 48 的密钥 */
bitset<48> GetSubKey(bitset<28> &key1, bitset<28> &key2, int round)
{
key1 = LeftShift(key1, round);
key2 = LeftShift(key2, round);
bitset<56> key = key1 + key2;
string str = "";
for (int i = 0; i < 48; ++i)
str += key[TransIndex(56, PC_2[i] - 1)] + ‘0‘;
return bitset<48>(str);
}
/* 生成 16 轮密钥 */
/* 每一轮的 subKey1, subKey2 都由上一轮修改给出 */
/* input: 用来存储 16 轮密钥的 vector,初始密钥 bitset<64> key */
/* output: none */
void GenKey(vector<bitset<48>> &K, const bitset<64> &key)
{
/* 对密钥进行置换 */
bitset<56> handledKey = KeyPermutation(key);
bitset<28> subKey1(handledKey.to_string().substr(0, 28));
bitset<28> subKey2(handledKey.to_string().substr(28, 28));
/* 生成每一轮的密钥 */
for (int i = 1; i <= 16; ++i) {
bitset<48> subKey = GetSubKey(subKey1, subKey2, i - 1);
K[i] = subKey;
}
}
/* 用每一轮的密钥加密每一轮的输入 */
/* input: 每一轮的输入明文 input, 每一轮的密钥 key */
/* output: 每一轮的密文 */
bitset<32> func(const bitset<32> &input, const bitset<48> &key)
{
/* 生成 bitset<48> 扩展明文 */
string str = "";
for (int i = 0; i < 48; ++i) str += input[TransIndex(32, E[i] - 1)] + ‘0‘;
bitset<48> expandedInput(str);
/* 生成异或值 */
bitset<48> xorRes = expandedInput ^key;
/* 将异或值分成 8 组 bitset<6> */
vector<bitset<6>> xorResGroup(8);
string temp = "";
for (int i = 47; i >= 0; --i) {
temp += xorRes[i] + ‘0‘;
if (i % 6 == 0) {
xorResGroup[i / 6] = bitset<6>(temp);
temp = "";
}
}
reverse(xorResGroup.begin(), xorResGroup.end());
/* 根据 bitset<6> 查询 S 盒,转化为 8 组 bitset<4> */
vector<bitset<4>> retGroup(8);
for (int i = 0; i < 8; ++i) {
bitset<6> xorResGroupMember = xorResGroup[i];
int x = 0, y = 0;
for (int j = 5; j >= 0; --j) { // 根据秦九韶算法从高位往第位计算
if (j == 0 || j == 5) x *= 2, x += xorResGroupMember[j];
else y *= 2, y += xorResGroupMember[j];
}
int target_val = S_BOX[i][x][y];
bitset<4> retGroupMember(target_val);
retGroup[i] = retGroupMember;
}
/* 将 8 组 bitset<4> 组成 bitset<32> */
str = "";
for (int i = 0; i < 8; ++i) {
str += retGroup[i].to_string();
}
string str2 = "";
/* 对输出的 bitset<32> 进行 P 置换 */
for (int i = 0; i < 32; ++i)
str2 += str[P[i] - 1];
return bitset<32>(str2);
}
/* 将 bitset<32> L, R 合并后逆置换输出 */
/* input: bitset<32> L, R */
/* output: 合并并且逆置换后的 bitset<64> 结果*/
bitset<64> InversePermutation(bitset<32> &L, bitset<32> &R)
{
bitset<64> res = L + R;
string str = "";
for (int i = 0; i < 64; ++i)
str += res[TransIndex(64, IP_inverse[i] - 1)] + ‘0‘;
return bitset<64>(str);
}
/* 加密 */
/* input: 明文 message,密钥 key*/
/* output: 密文 */
bitset<64> Encrypt(const bitset<64> &message, const vector<bitset<48>> &K)
{
/* 置换明文 */
vector<bitset<32>> handledMessage = InitialPermutation(message);
/* 生成 16 轮 L, R */
vector<bitset<32>> L(17);
vector<bitset<32>> R(17);
L[0] = handledMessage[0];
R[0] = handledMessage[1];
for (int i = 1; i <= 16; ++i) {
L[i] = R[i - 1];
R[i] = L[i - 1] ^ func(R[i - 1], K[i]);
}
/* 逆置换明文 */
bitset<64> ret = InversePermutation(R[16], L[16]);
return ret;
}
/* 解密 */
/* input: 密文 message,密钥 key*/
/* output: 明文 */
bitset<64> Decrypt(const bitset<64> &secret, const vector<bitset<48>> &K)
{
/* 置换明文 */
vector<bitset<32>> handledMessage = InitialPermutation(secret);
/* 生成 16 轮 L, R */
vector<bitset<32>> L(17);
vector<bitset<32>> R(17);
L[0] = handledMessage[0];
R[0] = handledMessage[1];
for (int i = 1; i <= 16; ++i) {
L[i] = R[i - 1];
R[i] = L[i - 1] ^ func(R[i - 1], K[17 - i]);
}
/* 逆置换明文 */
bitset<64> ret = InversePermutation(R[16], L[16]);
return ret;
}
/* 二进制转十六进制 */
/* input: 二进制串 */
/* output: 十六进制串 */
string Bin2Hex(string Bin)
{
string Hex = "0x";
int temp = Bin[0] - ‘0‘;
for (int i = 1; i <= Bin.length(); ++i) {
if (i % 4 == 0) {
Hex += temp >= 10 ? temp - 10 + ‘a‘ : temp + ‘0‘;
temp = 0;
}
if (i < Bin.length()) temp *= 2, temp += Bin[i] - ‘0‘;
}
return Hex;
}
int main()
{
bitset<64> m("0111001001101111011011010110000101101110011101000110100101100011");
bitset<64> k("0001001100110100010101110111100110011011101111001101111111110001");
/* 生成 16 轮 key */
vector<bitset<48>> K(17);
GenKey(K, k);
cout << "input: " << Bin2Hex(m.to_string()) << endl;
cout << "key: " << Bin2Hex(k.to_string()) << endl;
bitset<64> secret = Encrypt(m, K);
bitset<64> plaintext = Decrypt(secret, K);
cout << "secret: " << Bin2Hex(secret.to_string()) << endl;
cout << "Decrypted plaintext: " << Bin2Hex(plaintext.to_string()) << endl;
return 0;
}
原文:https://www.cnblogs.com/ChenyangXu/p/14618591.html