РЕДАКТИРОВАТЬ - - Я переименовал этот заголовок и изменил формулировку вопроса, поскольку некоторые отметили, что это скорее алгоритм хеширования, чем алгоритм шифрования-дешифрования.Тем не менее, я заквашу название функций такими, какие они есть.Я также добавлю свой полный код в конце вместе со ссылкой, где вы можете найти файл словаря, который я использую, поскольку некоторые не были уверены, где или как я генерировал числа, которые будут использоваться в алгоритме (ах).-
Я работаю над нестандартным алгоритмом, и пока результаты кажутся хорошими для первой части.Однако расчет, который я использую для обратного, я не уверен, есть ли один или нет.
Псевдокод выглядит следующим образом:
for each character in string:
new character in return string = (a|b) & c + 'a';
where:
a is a large value based on the occurrence of that character
based on an alpha text dictionary file
b is a small value based on the occurrence of that character
found in the analyzed string to be encrypted.
c is the current string converted to lowercase.
Моя функция шифрования:
std::string encrypt(const std::string& sentence, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::string encrypted = "";
// take each character from our original sentence
// find it in the map and perform the calculation.
// if the character is non alphabetical just add it.
for (auto& s : sentence)
if (std::isalpha(s)) {
char c = std::tolower(s);
char a = dist[std::remove_const_t<char>(c)].first; // large value
char b = dist[std::remove_const_t<char>(c)].second; // small value
char res = (a | b) % c + 'a';
encrypted.push_back(res);
}
else
encrypted.push_back(s);
return encrypted;
}
Функция дешифрования:
std::string decrypt(const std::string& encrypted, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::string decrpyted = "";
for (auto& s : encrypted) {
// ? Is there an inverse to the above?
// Also how would I handle the non alpha characters that
// were unchanged?
}
return decrpyted;
}
Я изменилрезультат функции к этому:
char res = (a % b) % c + 'a';
Текст кажется зашифрованным.Есть ли способ отменить это?
EDIT - -Полный исходный код и ссылка на файл словаря-
Github: Файл словаря
Полный источник
#include <cctype>
#include <climits>
#include <iostream>
#include <iterator>
#include <fstream>
#include <map>
#include <sstream>
void generateCryptoBaseMapFromFile(std::string filename, std::map<char, unsigned>& weights);
void printWeights(std::string filename, std::map<char, unsigned> weights);
void analyzeTextAndGenerateDistributionMap(std::string contents, std::map<char,unsigned>& weights, std::map<char, std::pair<unsigned, unsigned>>& dist);
void printDistributionMap(std::string filename, std::map<char, std::pair<unsigned, unsigned>>& dist);
std::string encrypt(const std::string& sentence, std::map<char, std::pair<unsigned, unsigned>>& dist);
std::string decrypt(const std::string& encrypted, std::map<char, std::pair<unsigned, unsigned>>& dist);
int main() {
std::string filenameIn( "words_alpha.txt" );
std::map<char, unsigned> weights;
generateCryptoBaseMapFromFile(filenameIn, weights);
std::string filenameOut("character_distribution.txt");
printWeights(filenameOut, weights);
std::cout << '\n';
std::string sentence("I enjoyed myself when I went to the shore. I had a blast swimming in the cool ocean on a hot summer day with a mild breeze.");
std::map<char, std::pair<unsigned, unsigned>> distMap;
analyzeTextAndGenerateDistributionMap(sentence, weights, distMap);
printDistributionMap(filenameOut, distMap);
std::cout << '\n';
std::string encrypted = encrypt(sentence, distMap);
std::cout << encrypted << '\n';
// std::string decrypted = decrypt(encrypted, dist);
// std::cout << decrypted << '\n'; // should match original sentence.
return EXIT_SUCCESS;
}
void generateCryptoBaseMapFromFile(std::string filename, std::map<char, unsigned>& weights) {
unsigned int count[1U << CHAR_BIT]{};
std::ifstream in;
in.open(filename);
if (!in.is_open()) {
std::cout << "Could not open " << filename << " for reading.";
return;
}
for (std::istream_iterator<char> it(in), it_eof; it != it_eof; ++it)
++count[std::tolower(static_cast<unsigned char>(*it))];
for (unsigned i = 0; i < (1U << CHAR_BIT); ++i)
if (std::isalpha(i) && count[i])
weights[static_cast<char>(i)] = count[i];
in.close();
}
void printWeights(std::string filename, std::map<char, unsigned> weights) {
std::ostringstream ostream;
for (auto& u : weights)
ostream << u.first << ' ' << u.second << '\n';
// print to file & cout
std::ofstream out;
out.open(filename, std::ios::trunc);
out << ostream.str();
std::cout << ostream.str();
}
void analyzeTextAndGenerateDistributionMap(std::string contents, std::map<char,unsigned>& weights, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::cout << "\nAnalyzing the following sentence:\n" << contents << '\n';
unsigned int count[1U << CHAR_BIT]{};
std::istringstream istream( contents );
for (std::istream_iterator<char> it(istream), it_eof; it != it_eof; ++it)
++count[std::tolower(static_cast<unsigned char>(*it))];
for (unsigned i = 0; i < (1U << CHAR_BIT); ++i) {
if (std::isalpha(i) && count[i]) {
unsigned weight = weights.at(static_cast<unsigned char>(i));
dist[static_cast<unsigned char>(i)] = std::make_pair(weight, count[i]);
}
}
}
void printDistributionMap(std::string filename, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::ofstream out;
out.open(filename, std::ios::app);
std::ostringstream os;
os << "\n\n";
out << os.str();
std::cout << os.str();
os.str(std::string());
os.clear();
for (auto& m : dist) {
os << m.first << " (" << m.second.first << "," << m.second.second << ")\n";
}
out << os.str();
std::cout << os.str();
}
std::string encrypt(const std::string& sentence, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::string encrypted = "";
// take each character from original string find it in the map
// and perform the calculations. If the character is non
// alpahbetical we just add it to the string.
for (auto& s : sentence)
if (std::isalpha(s)) {
char c = std::tolower(s);
char a = dist[c].first;
char b = dist[c].second;
// the following formula must have an inverse!
unsigned char res = (a % (b * c)) /*+ 'a'*/;
std::cout << +res << ' ';
encrypted.push_back(res);
}
else
encrypted.push_back(s);
std::cout << "\n\n";
return encrypted;
}
std::string decrypt(const std::string& encrypted, std::map<char, std::pair<unsigned, unsigned>>& dist) {
std::string decrpyted = "";
for (auto& s : encrypted) {
// ???
}
return decrpyted;
}