首页 > 解决方案 > 单字节异或密码 cpp

问题描述

我应该使用一个字符来破译一个十六进制字符串。我为每个 char(0-255) 运行了一个循环,并为自己获取了这些字符串的向量。现在,我正在尝试应用 etaoin shrdlu 方法来获得字符串中字母的最佳频率,这样我就不必手动检查正确的破译字符串。我正在粘贴我的代码,代码正在编译但没有打印任何内容。如果有人可以帮忙

#include<bits/stdc++.h>

using namespace std;


int hexchartoint(char hex){

    hex=tolower(int(hex));

    if(hex>='0' && hex<='9')
        return hex-'0';
    if(hex>='a' && hex<='f')
        return hex-'a'+10;
}

unordered_map<char,int> counter(string s){

    unordered_map<char,int> ma;
    for(int i=0;s[i]!='\0';i++)
        ma[s[i]]++;
}



int main(){

    string s;
    cin>>s;


    //unordered_map<char,int> ma;


    vector<pair<char,float>> etaoin;

    etaoin.push_back(make_pair('a',8.24));
    etaoin.push_back(make_pair('b',1.50));
    etaoin.push_back(make_pair('c',2.80));
    etaoin.push_back(make_pair('d',4.29));
    etaoin.push_back(make_pair('e',12.81));
    etaoin.push_back(make_pair('f',2.25));
    etaoin.push_back(make_pair('g',2.03));
    etaoin.push_back(make_pair('h',6.15));
    etaoin.push_back(make_pair('i',6.15));
    etaoin.push_back(make_pair('j',0.15));
    etaoin.push_back(make_pair('k',0.78));
    etaoin.push_back(make_pair('l',4.06));
    etaoin.push_back(make_pair('m',2.43));
    etaoin.push_back(make_pair('n',6.80));
    etaoin.push_back(make_pair('o',7.58));
    etaoin.push_back(make_pair('p',1.94));
    etaoin.push_back(make_pair('q',0.09));
    etaoin.push_back(make_pair('r',6.04));
    etaoin.push_back(make_pair('s',6.38));
    etaoin.push_back(make_pair('t',9.13));
    etaoin.push_back(make_pair('u',2.78));
    etaoin.push_back(make_pair('v',0.98));
    etaoin.push_back(make_pair('w',2.38));
    etaoin.push_back(make_pair('x',0.15));
    etaoin.push_back(make_pair('y',1.99));
    etaoin.push_back(make_pair('z',0.07));


    vector<int> v;
    for(int i=0;s[i]!='\0';i++)
        v.push_back(hexchartoint(s[i]));

    vector<int> pairs;
    for(int i=0;i<v.size();i+=2)
        pairs.push_back(v[i]*16 + v[i+1]);

    vector<string> fin;
    string z="";
    for(int i=0;i<256;i++){
        //vector<string> fin1;

        for(int j=0;j<pairs.size();j++){
            pairs[j]^=i;
            z+=pairs[j];
            //ma[pairs[j]]++;
        }
        fin.push_back(z);
        z="";

    }

    /*for(int i=0;i<fin.size();i++){
        cout<<fin[i]<<endl;
    }*/


    float fittingQuotient=INT_MAX;
    string answer="";

    for(int i=0;i<fin.size();i++){
        int len=fin[i].length();
        unordered_map<char,int> inside1=counter(fin[i]);
        unordered_map<char,float> inside2;

        for(int i=0;i<=25;i++){
            if(inside1[i+'a']!=0){
                inside2[i+'a']=(int(i+'a')*100)/len;
                //inside1[i]=INT_MAX;
            }
        }

        float temp=0;
        for(int i=0;i<=25;i++){
                //float a=etaoin[i+'a'];float b=inside2[i+'a'];
            temp+=etaoin[i].second - inside2[i+'a'];
        }
        temp/=inside1.size();

        if(temp<fittingQuotient){
            fittingQuotient=temp;
            answer=fin[i];
        }

    }


    cout<<answer<<endl;








    return 0;



}

标签: c++cryptography

解决方案


您的代码存在许多问题,并且您在此处发布的方式并不能轻松识别所有问题。

主要问题,可能是您的问题的原因是counter(string s)永远不会返回您在内部构建的地图:

unordered_map<char,int> counter(string s){
    unordered_map<char,int> ma;
    for(int i=0;s[i]!='\0';i++)
        ma[s[i]]++;

    return ma; // <- this was missing
}

有类似的问题hexchartoint(char hex),它不会为不正确的输入返回值。

非 void 函数必须在所有控制路径中返回一个值,否则您会遇到未定义的行为。

另一件事是,如果您打开编译器警告,您将永远不会遇到这种麻烦。你怎么做取决于编译器,因为 gcc 的典型标志是-Wall -Wextra


推荐阅读