/
malebranche
/
networks_omgtu
Обзор
Документация
Войти
/
malebranche
/
networks_omgtu
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
hamming_code.cpp
392 строки
13 KB
zero
Доделаны все, кроме Бургер Кода
07 ноя 2025, 13:12
07 ноя 2025, 13:12
704cb2c
Код
Авторство
О чём код?
#include <iostream> #include <cmath> #include <cstring> #include <bitset> #include <ctime> typedef unsigned short uint16; typedef unsigned char uint8; typedef unsigned int uint32; /* Код Хэмминга */ typedef uint32 BitIndex; #define DEBUG class HamsterCode{ public: HamsterCode(const char* message) { int message_size = strlen(message); /* Подсчёт количества необходимых контрольных бит */ uint32 maskOff = 0b01000000000000000000000000000000; while ((message_size & maskOff) == 0) { maskOff >>= 1; } std::cout << maskOff << std::endl; int control_bits_number = (int)sqrt(maskOff); // - - - - - - - - - - - - - - packets_number = (message_size * 8 + control_bits_number) / 32 + 1; // std::cout << packets_number << std::endl; MESSAGE_STREAM = (uint32**)malloc(packets_number * sizeof(uint32*)); int index = 0; /* Формирование пакетов по 32 бит (по 2 символа на пакет + контрольные биты) */ std::bitset<32> x(0); uint32 maskValue = 0; for (int i = 0; i < packets_number; i++) { MESSAGE_STREAM[i] = (uint32*)malloc(sizeof(uint32)); for (int j = 0; j < 3; j++) { if (j == 0) { maskValue = message[index]; maskValue <<= 22; MESSAGE_STREAM[i][0] |= maskValue; } else if (j == 1) { maskValue = message[index]; maskValue <<= 14; MESSAGE_STREAM[i][0] |= maskValue; } else if (j == 2) { maskValue = message[index]; maskValue <<= 6; MESSAGE_STREAM[i][0] |= maskValue; } index++; } x = *MESSAGE_STREAM[i]; std::cout << "Оригинальный пакет: " << x << std::endl; insert_control_bits(MESSAGE_STREAM[i]); } } ~HamsterCode() { for (int i = 0; i < packets_number; i++) { free(MESSAGE_STREAM[i]); } free (MESSAGE_STREAM); } /* ~Destructor */ int insert_control_bits(uint32* message) { std::bitset<32> x(0); // Value 00010001110011101010011100100000 // || // 00001000011100111001010011100100 // 01000111 01110101 01110010 /* 1,2, 4 бит */ x = *message; // std::cout << x << std :: endl; uint32 temp = *message; uint32 mask = 0b11100000000000000000000000000000; // Вытягиваем первые 4 бита исходного сообщения x = temp; // 0b00100000000000000000000000000000 temp = *message & mask; // Берем следующие 4 бита и смещаем вправо (место под 4 бит) temp |= ((*message & 0b00011110000000000000000000000000) >> 1); x = temp; // std::cout << x << std::endl; // Берем следующие 7 бит и смещаем вправо (место под 8 бит) temp |= ((*message & 0b00000001111110000000000000000000) >> 2); x = temp; // std::cout << x << std::endl; // Берем оставшиеся 16 бит и смещаем вправо (место под 16 бит) temp |= ((*message & 0b00000000000001111111111111111111) >> 3); x = temp; // std::cout << x << std::endl; // std::cout << x << std::endl; /* Вставляем 1 и 2 и 4 контрольные биты на место */ insert_control_bit_in_position(1, &temp); insert_control_bit_in_position(2, &temp); insert_control_bit_in_position(4, &temp); insert_control_bit_in_position(8, &temp); insert_control_bit_in_position(16, &temp); *message = temp; x = temp; std::cout << "Сгенерирован пакет: " << x << std::endl; return 0; } uint8 verify_control_bits(uint32* message) { uint8 bit_index = 0; std::bitset<32> b(*message); std::cout << "VERIFY_CONTROL_BLOCK: \nПравильное сообщение: " << b << std::endl; #ifdef DEBUG // TODO: Продебажить result_of_comparing *message |= 0b00000000000000000000000000000000; #endif b = *message; std::cout << "VERIFY_CONTROL_BLOCK: \nПолученное сообщение: " << b << std::endl; uint32 mask = 0b10000000000000000000000000000000; uint8 result_of_comparing = 0; int res = 0; for (int each_control_bit = 1; each_control_bit <= 16; each_control_bit *= 2) { res = 0; if (each_control_bit == 1) { mask = 0b10101010101010101010101010101010; } else if (each_control_bit == 2) { mask = 0b00100110011001100110011001100110; } else if (each_control_bit == 4) { mask = 0b00001110000111100001111000011110; } else if (each_control_bit == 8) { mask = 0b00000000111111100000000111111110; } else if (each_control_bit == 16) { mask = 0b00000000000000001111111111111111; } uint32 controled_bits = (*message & mask); mask = 0b10000000000000000000000000000000; for (int each_bit = 1; each_bit <= 32; each_bit++) { // t = mask; // std::cout << std::endl << "Mask: " << t << std::endl; if ((controled_bits & mask) > 0) { res++; } mask >>= 1; } // Маска для получения контрольного бита mask = (each_control_bit == 0 ? 0b10000000000000000000000000000000 : (0b10000000000000000000000000000000 >> (each_control_bit - 1))); b = mask; // std::cout << "Mask: " << b << std::endl; /* Получение нашего контрольного бита */ // 00001000011101111010101110010000 // Контрольный бит uint8 bit = (*message & mask) > 0 ? 1 : 0; // Вычисленная сумма uint8 expected_bit = res % 2 == 0 ? 0 : 1; // result_of_comparing |= ((bit ^ expected_bit) >> (each_control_bit / 2)); // bit ^ expected_bit // each_control_bit : 1 2 4 8 16 result_of_comparing |= ((bit ^ expected_bit) << bit_index); std::bitset<8> val(result_of_comparing); // std::cout << "Полученное значение: " << val << std::endl; bit_index++; } std::bitset<32> x(result_of_comparing); // std:: cout << "Результат сравнения : " << x << std::endl; return result_of_comparing; } uint32** MESSAGE_STREAM {nullptr}; int recieve_packet(uint32** packet_stream) { /* Сгенерирован пакет: 00001000011101111010101110010000 Изначальный пакет: 00010001110111010101110010000000 */ int corrupted_packets_n = 0; // 00010001110111010101110010000000 uint32* packet_ptr {nullptr}; for (int packet_index = 0; packet_index < packets_number; packet_index++ ) { packet_ptr = *(packet_stream+packet_index); uint32 resulting_bits = verify_control_bits(packet_ptr); if (resulting_bits == 0) { std::cout << "Сообщение доставлено без ошибок!\n" << std::endl; } else { corrupted_packets_n++; std::cout << "Ошибка в бите " << resulting_bits << std::endl; } } std::cout << "Отправлено сообщений: " << packets_number << ". Из них передано с ошибкой: " << corrupted_packets_n << std::endl; return 0; } int generate_error(uint32** packet_stream) { uint32* packet_ptr {nullptr}; uint32 mask = 0b00000000000000100000000000000000; for (int packet_index = 0; packet_index < packets_number; packet_index++ ) { packet_ptr = *(packet_stream + packet_index); std::srand((__uint8_t)::std::time(NULL)); /* * offset - номер оффсета бита mask который будет меняться */ __uint8_t offset {(__uint8_t)(rand() % 5)}; __uint8_t vector {(__uint8_t)(rand() % 3)}; if (vector == 0) { *packet_ptr &= ((mask << offset ) ^ 0b11111111111111111111111111111111); } else if (vector == 2) { *packet_ptr |= (mask << offset); } else { continue; } } return 0; } private: int packets_number{0}; void insert_control_bit_in_position(int bit_number, uint32* temp) { uint32 mask = 0b00000000000000000000000000000000; switch (bit_number) { case 1: { mask = 0b10101010101010101010101010101010; break; } case 2: { mask = 0b01100110011001100110011001100110; break; } case 4: { mask = 0b00011110000111100001111000011110; break; } case 8: { mask = 0b00000001111111100000000111111110; break; } case 16: { mask = 0b00000000000000011111111111111111; break; } default: { std::cerr << "Ошибка в строке 214. Ошибка в свитч."; return; } } // 11001100010001000000000 // 1000011101101010101110010000 uint32 controled_bits = (*temp & mask); int res = 0; uint32 bit = 0; std::bitset<32> t(*temp); t = controled_bits; // std::cout << std::endl << "Controlled bits: " << t << std::endl; /* * Здесь идет проход по всем битам формирующим контрольный бит bit_number */ // *temp == 00001000011101101010101110010000 8 единиц // controled_bits = 1000001000101010101010000000 // 1010101110010000 mask = 0b10000000000000000000000000000000; // #ifdef DEBUG // t = *temp; // std::cout << std::endl << "Value do: " << t << std::endl; // #endif for (int i = 1; i <= 32; i++) { // t = mask; // std::cout << std::endl << "Mask: " << t << std::endl; if ((controled_bits & mask) > 0) { res++; } mask >>= 1; } // Если четное то 0 if (res % 2 == 0) { *temp &= 0b11111111111111111111111111111111 ^ (0b10000000000000000000000000000000 >> (bit_number - 1)); } else // Если нечетное то 1 { *temp |= 0b10000000000000000000000000000000 >> (bit_number - 1); } // t = *temp; // std::cout << std::endl << "Value posle: " << t << std::endl; } }; int main() { const char* message = "Gurin Pavel Ruslanovich 13.06.2004."; HamsterCode HamsterInstance = HamsterCode(message); HamsterInstance.generate_error(HamsterInstance.MESSAGE_STREAM); HamsterInstance.recieve_packet(HamsterInstance.MESSAGE_STREAM); return 0; }