题目:CS255 密码学导论 (stanford.edu)
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<bitset>
using namespace std;
string hex2bi(string strHex)//将16进制转为2进制
{
string sReturn = "";
unsigned int len = strHex.length();
for (unsigned int i = 0; i < len; i++)
{
switch (strHex[i]){
case '0': sReturn.append("0000"); break;
case '1': sReturn.append("0001"); break;
case '2': sReturn.append("0010"); break;
case '3': sReturn.append("0011"); break;
case '4': sReturn.append("0100"); break;
case '5': sReturn.append("0101"); break;
case '6': sReturn.append("0110"); break;
case '7': sReturn.append("0111"); break;
case '8': sReturn.append("1000"); break;
case '9': sReturn.append("1001"); break;
case 'a': sReturn.append("1010"); break;
case 'b': sReturn.append("1011"); break;
case 'c': sReturn.append("1100"); break;
case 'd': sReturn.append("1101"); break;
case 'e': sReturn.append("1110"); break;
case 'f': sReturn.append("1111"); break;
}
}
//cout<<sReturn<<endl;
return sReturn;
}
string XOR(string b1,string b2) //对两个2进制字符串求异或
{
int len = min(b1.length(), b2.length());
string ans = "";
for (int i = 0; i < len; i++)
{
b1[i] == b2[i] ? ans.append("0") : ans.append("1");
}
//cout << ans << endl;
return ans;
}
vector<int> bi2ascll(string s) //将异或结果进行分割,计算出十进制数,符合字母的表示出来,存储位数
{
string byte = "";
vector<string> ans;
for (auto y:s) {
if (byte.length()==8) {
ans.push_back(byte);
byte = "";
}
byte.push_back(y);
}
int cnt = 0;
vector<int> vnum;
for (auto x : ans) {
int num = 0;
//cout << cnt << " " << cnt + 1 << " " << x << " ";
for (int z = 0; z < 8; z++) {
num += (x[z] - '0') * pow(2, 7 - z);
}
if ((65 <= num && num <= 90) || (97 <= num && num <= 122)) {
//cout << char(num) << ' ';
vnum.push_back(cnt);
vnum.push_back(cnt+1);
}
//cout << num << '\n';
cnt += 2;
}
//cout << endl;
//for (auto t : vnum)
// cout << t << "\n";
//cout << endl;
return vnum;
}
string mark(vector<int> vnum,string s1, string s2) {//将对比文的标记处改为#
for (auto i : vnum) {
if (i > s1.length())
break;
s1[i] = '#';
}
//for (auto j : s1)
// cout << j;
//cout << "\n" << endl;
//for (auto i : vnum) {
// if (i > s2.length())
// break;
// s2[i] = '#';
//}
//for (auto j : s2)
// cout << j;
//cout << endl;
return s1;
}
void change(vector<char>&ans,string s,string target,int n) {
string x = XOR(hex2bi(s.substr(n, 2)), hex2bi(target.substr(n, 2)));
int num = 0;
for (int i = 0; i < 8; i++) {
num += (x[i] - '0') * pow(2, 7 - i);
}
ans[n / 2] = tolower(char(num));
}
int main() {
string ciphertext1 = "315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e";
string ciphertext2 = "234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f";
string ciphertext3 = "32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb";
string ciphertext4 = "32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa";
string ciphertext5 = "3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070";
string ciphertext6 = "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4";
string ciphertext7 = "32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce";
string ciphertext8 = "315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3";
string ciphertext9 = "271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027";
string ciphertext10 = "466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83";
string targetciphertext = "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904";
//README
//使用时将str1改为要对比的密文
string str1 = ciphertext9;
vector<string> collect;
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext1))), str1, ciphertext1));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext2))), str1, ciphertext2));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext3))), str1, ciphertext3));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext4))), str1, ciphertext4));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext5))), str1, ciphertext5));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext6))), str1, ciphertext6));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext7))), str1, ciphertext7));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext8))), str1, ciphertext8));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext9))), str1, ciphertext9));
collect.push_back(mark(bi2ascll(XOR(hex2bi(str1), hex2bi(ciphertext10))), str1, ciphertext10));
for (auto i : collect)
cout << i << "\n" << endl;
int len = str1.length();
vector<int> count(len, 0);
for (auto i : collect)
{
for (int j = 0; j < len; j++)
{
if (i[j] == '#')
count[j]++;
}
}
for (int i = 0; i < targetciphertext.length(); i++)
if (count[i] >= 6) //调整下限
cout << i << ":" << count[i] << "\n";
cout << endl;
vector<char> ans(targetciphertext.length()/2, '0');
change(ans, ciphertext10, targetciphertext, 0);
change(ans, ciphertext9, targetciphertext, 2);
change(ans, ciphertext8, targetciphertext, 4);
change(ans, ciphertext5, targetciphertext, 6);
change(ans, ciphertext10, targetciphertext, 8);
change(ans, ciphertext7, targetciphertext, 10);
change(ans, ciphertext1, targetciphertext, 12);
change(ans, ciphertext5, targetciphertext, 14);
change(ans, ciphertext3, targetciphertext, 16);
change(ans, ciphertext7, targetciphertext, 18);
change(ans, ciphertext8, targetciphertext, 20);
change(ans, ciphertext10, targetciphertext, 24);
change(ans, ciphertext2, targetciphertext, 22);
change(ans, ciphertext7, targetciphertext, 26);
change(ans, ciphertext9, targetciphertext, 30);
change(ans, ciphertext9, targetciphertext, 32);
change(ans, ciphertext5, targetciphertext, 34);
change(ans, ciphertext5, targetciphertext, 42);
change(ans, ciphertext6, targetciphertext, 38);
change(ans, ciphertext8, targetciphertext, 40);
change(ans, ciphertext6, targetciphertext, 44);
change(ans, ciphertext4, targetciphertext, 46);
change(ans, ciphertext1, targetciphertext, 48);
change(ans, ciphertext1, targetciphertext, 50);
change(ans, ciphertext4, targetciphertext, 52);
change(ans, ciphertext9, targetciphertext, 54);
change(ans, ciphertext3, targetciphertext, 56);
change(ans, ciphertext10, targetciphertext, 58);
change(ans, ciphertext8, targetciphertext, 60);
change(ans, ciphertext10, targetciphertext, 62);
change(ans, ciphertext1, targetciphertext, 64);
change(ans, ciphertext4, targetciphertext, 66);
change(ans, ciphertext5, targetciphertext, 68);
change(ans, ciphertext5, targetciphertext, 70);
change(ans, ciphertext6, targetciphertext, 72);
change(ans, ciphertext6, targetciphertext, 74);
change(ans, ciphertext3, targetciphertext, 76);
change(ans, ciphertext2, targetciphertext, 78);
change(ans, ciphertext1, targetciphertext, 80);
change(ans, ciphertext9, targetciphertext, 82);
change(ans, ciphertext6, targetciphertext, 84);
change(ans, ciphertext9, targetciphertext, 86);
change(ans, ciphertext7, targetciphertext, 88);
change(ans, ciphertext10, targetciphertext, 90);
change(ans, ciphertext5, targetciphertext, 92);
change(ans, ciphertext2, targetciphertext, 94);
change(ans, ciphertext6, targetciphertext, 96);
change(ans, ciphertext8, targetciphertext, 98);
change(ans, ciphertext5, targetciphertext, 100);
change(ans, ciphertext8, targetciphertext, 102);
change(ans, ciphertext10, targetciphertext, 104);
change(ans, ciphertext6, targetciphertext, 106);
change(ans, ciphertext1, targetciphertext, 108);
change(ans, ciphertext2, targetciphertext, 110);
change(ans, ciphertext8, targetciphertext, 114);
change(ans, ciphertext1, targetciphertext, 116);
change(ans, ciphertext10, targetciphertext, 118);
change(ans, ciphertext4, targetciphertext, 120);
change(ans, ciphertext8, targetciphertext, 122);
change(ans, ciphertext9, targetciphertext, 124);
change(ans, ciphertext1, targetciphertext, 126);
change(ans, ciphertext9, targetciphertext, 128);
change(ans, ciphertext3, targetciphertext, 130);
change(ans, ciphertext5, targetciphertext, 132);
change(ans, ciphertext10, targetciphertext, 134);
change(ans, ciphertext4, targetciphertext, 136);
change(ans, ciphertext3, targetciphertext, 138);
change(ans, ciphertext2, targetciphertext, 140);
change(ans, ciphertext6, targetciphertext, 142);
change(ans, ciphertext3, targetciphertext, 144);
change(ans, ciphertext8, targetciphertext, 146);
change(ans, ciphertext9, targetciphertext, 148);
change(ans, ciphertext10, targetciphertext, 150);
change(ans, ciphertext6, targetciphertext, 152);
change(ans, ciphertext10, targetciphertext, 154);
change(ans, ciphertext9, targetciphertext, 156);
change(ans, ciphertext10, targetciphertext, 158);
change(ans, ciphertext2, targetciphertext, 160);
change(ans, ciphertext6, targetciphertext, 162);
change(ans, ciphertext2, targetciphertext, 164);
for (auto i : ans) {
cout << i;
}
cout << endl;
}