Last active
March 2, 2021 07:53
-
-
Save EugW/8c07e7f2906f4dfcab9026863041a714 to your computer and use it in GitHub Desktop.
Hamming code assignment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <string> | |
using namespace std; | |
string encode(string original); // Прототип функции посимвольного кодирования | |
string decode(string original); // Прототип функции декодирования кода | |
string corrupt(string original); // Прототип функции внесения одиночных ошибок | |
string repair(string original); // Прототип функции поиска и исправления ошибки | |
int main() { | |
ifstream input; | |
input.open("input.txt"); // Открытие файла для чтения | |
string original; | |
input >> original; | |
input.close(); | |
cout << "ORGINIAL TEXT : " << original << endl; | |
string encoded = encode(original); | |
cout << "ENCODED TEXT : " << encoded << endl; // Вывод закдированной строки | |
string corrupted = corrupt(encoded); | |
cout << "CORRUPTED TEXT : " << corrupted << endl; // Вывод поврежденной строки | |
string repaired = repair(corrupted); | |
cout << "REPAIRED TEXT : " << repaired << endl; // Вывод исправленной строки | |
string decoded = decode(repaired); | |
cout << "DECODED TEXT : " << decoded << endl; // Декодирование исправленной строки | |
cout << "CONCLUSION: ENCODED TEXT " << (encoded == repaired ? | |
"\x1B[32mMATCHES\033[0m " : | |
"\x1B[31mDOESN'T MATCH\033[0m ") << "REPAIRED TEXT" << endl; // Вывод: сравнение кода исходной строки и исправленной | |
ofstream output; | |
output.open("output.txt"); // Открытие файла для записи | |
output << repaired; // Вывод исправленной строки в файл | |
return 0; | |
} | |
string encode(string original) { // Функция посимвольного кодирования | |
string result; | |
for (int i = 0; i < original.length(); i++) { | |
string tmpStr; | |
char targetChar = original[i]; | |
int maxPow = (int) floor(log2(original[i])); // Максимально возможная степень двойки | |
int arrayH[12]; | |
int iter = 0; | |
int pwr; | |
for (int j = 0; j < 7 - maxPow; j++) | |
tmpStr += '0'; | |
while (targetChar > 0) { | |
pwr = (int)pow(2, maxPow); | |
if (targetChar >= pwr) { | |
targetChar -= pwr; | |
tmpStr += '1'; | |
} | |
else tmpStr += '0'; | |
maxPow--; | |
} | |
for (size_t j = tmpStr.length(); j < 8; j++) | |
tmpStr += '0'; | |
pwr = 1; | |
for (int j = 0; j < 12; j++) { | |
arrayH[j] = 0; | |
if (j != pwr - 1) { | |
if (tmpStr[iter++] == '1') | |
arrayH[j] = 1; | |
} | |
else | |
pwr *= 2; | |
} | |
pwr = 1; | |
for (int j = 0; j < 12; j++) | |
if (j == (pwr - 1)) { | |
int* ptr = arrayH + j; | |
int* ptrEnd = ptr + pwr; | |
while (ptr < arrayH + 12) { | |
arrayH[j] ^= *ptr; | |
ptr++; | |
if (ptr == ptrEnd) { | |
ptrEnd += pwr * 2; | |
ptr += pwr; | |
} | |
} | |
pwr *= 2; | |
} | |
for (int j = 0; j < 12; j++) | |
result += arrayH[j] == 1 ? '1' : '0'; | |
} | |
return result; | |
} | |
string decode(string original) { // Функция декодирования | |
string tmpStr; | |
string result; | |
for (int i = 0; i < original.length(); i += 12) { | |
string tmpSubstr = original.substr(i, 12); | |
int pwr = 1; | |
for (int j = 0; j < 12; ++j) | |
if (j != (pwr - 1)) | |
tmpStr += tmpSubstr[j]; | |
else | |
pwr *= 2; | |
} | |
for (int i = 0; i < tmpStr.length(); i += 8) { | |
string tmpSubstr = tmpStr.substr(i, 8); | |
reverse(tmpSubstr.begin(), tmpSubstr.end()); | |
char resultChar = 0; | |
for (int j = 0; j < 8; ++j) | |
if (tmpSubstr[j] == '1') | |
resultChar += (char) pow(2, j); | |
result += resultChar; | |
} | |
return result; | |
} | |
string corrupt(string original) { // Функция внесения ошибки | |
string result = original; | |
srand((unsigned int) time(NULL)); | |
for (int i = 0; i < original.length(); i += 12) { | |
if (rand() % 4 == 1) { // Вероятность ошибки 25% | |
int posOffset = i + rand() % 12; | |
result[posOffset] = result[posOffset] == '0' ? '1' : '0'; | |
} | |
} | |
return result; | |
} | |
string repair(string original) { // Функция восстановления поврежденного кода | |
string result; | |
for (int i = 0; i < original.length(); i += 12) { | |
string tmpSubstr = original.substr(i, 12); | |
string hammingStr; | |
for (int pwr = 1; pwr <= 8; pwr *= 2) { | |
int resInt = 0; | |
int offset = pwr - 1; | |
while (offset < tmpSubstr.length()) { | |
int endOffset = offset + pwr; | |
while (offset < endOffset) { | |
if (offset >= tmpSubstr.length()) | |
break; | |
resInt ^= tmpSubstr[offset] == '1' ? 1 : 0; | |
offset++; | |
} | |
offset += pwr; | |
} | |
hammingStr += to_string(resInt); | |
} | |
if (hammingStr != "0000") { | |
int errorPos = -1; | |
for (int j = 0; j < 4; ++j) | |
if (hammingStr[j] == '1') | |
errorPos += (int) pow(2, j); | |
tmpSubstr[errorPos] = tmpSubstr[errorPos] == '1' ? '0' : '1'; | |
} | |
result += tmpSubstr; | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment