Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #ifdef DEBUG_PRINTS_ENABLED
- #include <QTextStream>
- #include <iostream>
- #endif
- #include <cinttypes>
- #include <cmath>
- #include <iomanip>
- #include <sstream>
- #include <string>
- #include <vector>
- namespace Algorithms {
- struct CRCResult {
- std::string inputBits;
- std::string checksum;
- };
- struct HammingResult {
- std::string inputBits;
- std::string inputBitsWithControlBits;
- int controlBitsAmount;
- int dataBitsAmount;
- double dataControlRatio;
- bool singleErrorCorrected;
- bool doubleErrorDetected;
- };
- template <typename T>
- inline std::string _checksum_to_string(T checksum) {
- std::stringstream checksumStrStream;
- checksumStrStream << "0x" << std::hex << checksum;
- return checksumStrStream.str();
- }
- inline char _xor(char a, char b) {
- if (a == b) {
- return '0';
- }
- return '1';
- }
- template <typename MutIt, typename ConstIt>
- inline void _xor_poly(MutIt bits, ConstIt poly, std::size_t length) {
- for (std::size_t i = 0; i < length; i++) {
- *bits = _xor(*bits, *poly);
- bits++;
- poly++;
- }
- }
- // Bits - data bits in string for, for example "100010101"
- // Poly - CRC polynomial in bits form, for example "1011"
- // Filler - filler char, either '0' or '1'
- CRCResult crc(std::string const& bits, std::string const& poly, char filler) {
- CRCResult result{};
- #ifdef DEBUG_PRINTS_ENABLED
- QTextStream out(stdout);
- out << "Input bits: " << QString::fromStdString(bits)
- << ", poly: " << QString::fromStdString(poly) << " filler: " << filler
- << '\n';
- #endif
- // Step 1: create working string from data bits, right-padded with filler
- std::string padded_bits = bits + std::string(poly.length() - 1, filler);
- #ifdef DEBUG_PRINTS_ENABLED
- out << "Padded input bits: " << QString::fromStdString(padded_bits) << "\n";
- out.flush();
- #endif
- // Step 2: loop over the padded bits, and perform XOR with poly
- auto it = padded_bits.begin();
- #ifdef DEBUG_PRINTS_ENABLED
- out << QString::fromStdString(padded_bits) << '\n';
- #endif
- for (std::size_t i = 0; i < bits.length(); i++) {
- // If the MSB is not 1, continue
- if (*it == '0') {
- it++;
- continue;
- }
- #ifdef DEBUG_PRINTS_ENABLED
- out << QString(i, ' ') << QString::fromStdString(poly) << '\n';
- out << QString(padded_bits.length(), '-') << '\n';
- out.flush();
- #endif
- // XOR over the poly
- _xor_poly(it, poly.cbegin(), poly.length());
- #ifdef DEBUG_PRINTS_ENABLED
- out << QString::fromStdString(padded_bits) << '\n';
- #endif
- it++;
- }
- #ifdef DEBUG_PRINTS_ENABLED
- out << "Final result: " << QString::fromStdString(padded_bits) << '\n';
- out.flush();
- #endif
- // Step 3: take the checksum from data string and convert it to hex string
- std::string const checksum_binary_str = padded_bits.substr(bits.length());
- auto checksum_value = std::stoul(checksum_binary_str, nullptr, 2);
- result.inputBits = bits;
- result.checksum = _checksum_to_string(checksum_value);
- return result;
- }
- } // namespace Algorithms
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement