单字节异或密码C++解密代码编译通过无输出,如何用etaoin shrdlu修复
问题代码BUG列表
- 函数返回值缺失:
counter函数构建完字符计数的map后,没有执行return ma;语句,属于未定义行为,调用时拿到的是无效map,后续频率计算完全失效;hexchartoint函数也建议补充非法输入的默认返回,避免极端输入下的未定义行为。 - 异或逻辑错误:解密循环中直接修改了原始的
pairs数组(pairs[j]^=i;),导致第n次循环的异或基值是上一次修改后的结果,所有解密得到的字符串都是错误的,应该改为生成临时异或值不修改原数组。 - 频率计算逻辑完全错误:计算当前解密字符串的字符频率时,错误使用了字符的ASCII值参与计算,正确逻辑应该是用该字符的出现次数乘以100除以总长度。
- 拟合商计算逻辑错误:直接对频率差求和会导致正负误差抵消,无法正确反映匹配度,应该对差值取绝对值再求和;同时要避免
inside1为空时的除以0问题。 - 字符大小写未统一处理:解密后的字符串可能存在大写字母,统计频率时需要统一转成小写,否则会出现大写字符无法匹配到
etaoin频率表的问题。
修正后核心代码片段
// 修正后的十六进制字符转整数函数 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; return 0; // 补充非法输入默认返回 } // 修正后的字符计数函数 unordered_map<char,int> counter(string s){ unordered_map<char,int> ma; for(int i=0;s[i]!='\0';i++) ma[tolower(s[i])]++; // 统一转小写统计 return ma; // 补充返回值 } // 修正后的解密循环 vector<string> fin; for(int i=0;i<256;i++){ string z=""; for(int j=0;j<pairs.size();j++){ z += (char)(pairs[j] ^ i); // 不修改原pairs数组 } fin.push_back(z); } // 修正后的频率匹配部分 float fittingQuotient=INT_MAX; string answer=""; for(int i=0;i<fin.size();i++){ int len=fin[i].length(); if(len == 0) continue; unordered_map<char,int> inside1=counter(fin[i]); unordered_map<char,float> inside2; for(int j=0;j<26;j++){ char c = etaoin[j].first; inside2[c] = (inside1[c] * 100.0) / len; } float temp=0; for(int j=0;j<26;j++){ temp += abs(etaoin[j].second - inside2[etaoin[j].first]); } temp /= 26; if(temp < fittingQuotient){ fittingQuotient = temp; answer = fin[i]; } }
内容的提问来源于stack exchange,提问作者Bhavishyag2
相关产品推荐
相关产品推荐

