This code in C++ shows some errors help me fix it and help me put comments for each line. this code is for vigenere cipher
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <array>
using namespace std;
typedef array<pair<char, double>, 26> FreqArray;
class VigenereCipher
{
private:
array<double, 26> targets;
array<double, 26> sortedTargets;
FreqArray freq;
//the frequency array are updated
FreqArray& frequency(const string& input)
{
for (char c = ‘A’; c <= ‘Z’; ++c)
freq[c – ‘A’] = make_pair(c, 0);
for (size_t i = 0; i < input.size(); ++i)
freq[input[i] – ‘A’].second++;
return freq;
}
double correlation(const string& input)
{
double result = 0.0;
frequency(input);
sort(freq.begin(), freq.end(), [](pair<char, double> u, pair<char, double> v)->bool
{ return u.second < v.second; };
for (size_t i = 0; i < 26; ++i)
result += freq[i].second * sortedTargets[i];
return result;
}
public:
VigenereCipher(const array<double, 26>& targetFreqs)
{
targets = targetFreqs;
sortedTargets = targets;
sort(sortedTargets.begin(), sortedTargets.end());
}
pair<string, string> analyze(string input)
{
string cleaned;
for (size_t i = 0; i < input.size(); ++i)
{
if (input[i] >= ‘A’ && input[i] <= ‘Z’)
cleaned += input[i];
else if (input[i] >= ‘a’ && input[i] <= ‘z’)
cleaned += input[i] + ‘A’ – ‘a’;
}
size_t bestLength = 0;
double bestCorr = -100.0;
// Assume that if there are less than 20 characters
// per column, the key’s too long to guess
for (size_t i = 2; i < cleaned.size() / 20; ++i)
{
vector<string> pieces(i);
for (size_t j = 0; j < cleaned.size(); ++j)
pieces[j % i] += cleaned[j];
// The correlation increases artificially for smaller
// pieces/longer keys, so weigh against them a little
double corr = -0.5*i;
for (size_t j = 0; j < i; ++j)
corr += correlation(pieces[j]);
if (corr > bestCorr)
{
bestLength = i;
bestCorr = corr;
}
}
if (bestLength == 0)
return make_pair(“Text is too short to analyze”, “”);
vector<string> pieces(bestLength);
for (size_t i = 0; i < cleaned.size(); ++i)
pieces[i % bestLength] += cleaned[i];
vector<FreqArray> freqs;
for (size_t i = 0; i < bestLength; ++i)
freqs.push_back(frequency(pieces[i]));
string key = “”;
for (size_t i = 0; i < bestLength; ++i)
{
sort(freqs[i].begin(), freqs[i].end(), [](pair<char, double> u, pair<char, double> v)->bool
({ return u.second > v.second; });
size_t m = 0;
double mCorr = 0.0;
for (size_t j = 0; j < 26; ++j)
{
double corr = 0.0;
char c = ‘A’ + j;
for (size_t k = 0; k < 26; ++k)
{
int d = (freqs[i][k].first – c + 26) % 26;
corr += freqs[i][k].second * targets[d];
}
if (corr > mCorr)
{
m = j;
mCorr = corr;
}
}
key += m + ‘A’;
}
string result = “”;
for (size_t i = 0; i < cleaned.size(); ++i)
result += (cleaned[i] – key[i % key.length()] + 26) % 26 + ‘A’;
return make_pair(result, key);
}
};
int main()
{
string input =
“uvamqyfbmmturutrzjnzghrwimfbieksnzcyfcibglncbzsjaqibufgzinwizblfgynquanbyjmtfmqmgsnuuuopnpksdcvyxnmbgscnwhvrflaqwyerjcntkijvqzbcmbuijpmtfffqzuuypuqnmqzjblizinlpgsmqwxlcbmxfrmvuxwiaspxnpxpjxqtuxnpkgdncxfkobcfpizuvwxwxtlliscuywbfanpkpkmbgduyacfeyouucijownhwsbcnmxixqugohmsofbbibfoutrfw”;
array<double, 26> english = {array<double, 26> frequency = {.082,.015,.028,.043,.127,.022,.020,.061,.070,
.002,.008,.040,.024,.067,.075,.019,.001,.060,.063,.091,.028,.010,.023,.001,.020,.001};
};
VigenereCipher va(english);
pair<string, string> output = va.analyze(input);
cout << “The Key is: ” << output.second << endl << endl;
cout << “The decrypted Text is: ” << output.first << endl;
}
Expert Answer
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <array>
using namespace std;
typedef array<pair<char, double>, 26> FreqArray;
class VigenereCipher
{
private:
array<double, 26> targets;
array<double, 26> sortedTargets;
FreqArray freq;
//the frequency array are updated
FreqArray& frequency(const string& input)
{
for (char c = ‘A’; c <= ‘Z’; ++c)
freq[c – ‘A’] = make_pair(c, 0);
for (size_t i = 0; i < input.size(); ++i)
freq[input[i] – ‘A’].second++;
return freq;
}
double correlation(const string& input)
{
double result = 0.0;
frequency(input);
sort(freq.begin(), freq.end(), [](pair<char, double> u, pair<char, double> v)->bool
{ return u.second < v.second; }); // here you have missed ) at the end, in between };
for (size_t i = 0; i < 26; ++i)
result += freq[i].second * sortedTargets[i];
return result;
}
public:
VigenereCipher(const array<double, 26>& targetFreqs)
{
targets = targetFreqs;
sortedTargets = targets;
sort(sortedTargets.begin(), sortedTargets.end());
}
pair<string, string> analyze(string input)
{
string cleaned;
for (size_t i = 0; i < input.size(); ++i)
{
if (input[i] >= ‘A’ && input[i] <= ‘Z’)
cleaned += input[i];
else if (input[i] >= ‘a’ && input[i] <= ‘z’)
cleaned += input[i] + ‘A’ – ‘a’;
}
size_t bestLength = 0;
double bestCorr = -100.0;
// Assume that if there are less than 20 characters
// per column, the key’s too long to guess
for (size_t i = 2; i < cleaned.size() / 20; ++i)
{
vector<string> pieces(i);
for (size_t j = 0; j < cleaned.size(); ++j)
pieces[j % i] += cleaned[j];
// The correlation increases artificially for smaller
// pieces/longer keys, so weigh against them a little
double corr = -0.5*i;
for (size_t j = 0; j < i; ++j)
corr += correlation(pieces[j]);
if (corr > bestCorr)
{
bestLength = i;
bestCorr = corr;
}
}
if (bestLength == 0)
return make_pair(“Text is too short to analyze”, “”);
vector<string> pieces(bestLength);
for (size_t i = 0; i < cleaned.size(); ++i)
pieces[i % bestLength] += cleaned[i];
vector<FreqArray> freqs;
for (size_t i = 0; i < bestLength; ++i)
freqs.push_back(frequency(pieces[i]));
string key = “”;
for (size_t i = 0; i < bestLength; ++i)
{
sort(freqs[i].begin(), freqs[i].end(), [](pair<char, double> u, pair<char, double> v)->bool
{ return u.second > v.second; }); //here you have added one extra (
size_t m = 0;
double mCorr = 0.0;
for (size_t j = 0; j < 26; ++j)
{
double corr = 0.0;
char c = ‘A’ + j;
for (size_t k = 0; k < 26; ++k)
{
int d = (freqs[i][k].first – c + 26) % 26;
corr += freqs[i][k].second * targets[d];
}
if (corr > mCorr)
{
m = j;
mCorr = corr;
}
}
key += m + ‘A’;
}
string result = “”;
for (size_t i = 0; i < cleaned.size(); ++i)
result += (cleaned[i] – key[i % key.length()] + 26) % 26 + ‘A’;
return make_pair(result, key);
}
};
int main()
{
string input =
“uvamqyfbmmturutrzjnzghrwimfbieksnzcyfcibglncbzsjaqibufgzinwizblfgynquanbyjmtfmqmgsnuuuopnpksdcvyxnmbgscnwhvrflaqwyerjcntkijvqzbcmbuijpmtfffqzuuypuqnmqzjblizinlpgsmqwxlcbmxfrmvuxwiaspxnpxpjxqtuxnpkgdncxfkobcfpizuvwxwxtlliscuywbfanpkpkmbgduyacfeyouucijownhwsbcnmxixqugohmsofbbibfoutrfw”;
//in below line you have to create only english array, no need of frequeny
array<double, 26> english = {.082,.015,.028,.043,.127,.022,.020,.061,.070,
.002,.008,.040,.024,.067,.075,.019,.001,.060,.063,.091,.028,.010,.023,.001,.020,.001};
VigenereCipher va(english);
pair<string, string> output = va.analyze(input);
cout << “The Key is: ” << output.second << endl << endl;
cout << “The decrypted Text is: ” << output.first << endl;
}