CS255#1代码

题目: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值