SteelPh0enix

Untitled

May 14th, 2021
441
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2.  
  3. #ifdef DEBUG_PRINTS_ENABLED
  4. #include <QTextStream>
  5. #include <iostream>
  6. #endif
  7.  
  8. #include <cinttypes>
  9. #include <cmath>
  10. #include <iomanip>
  11. #include <sstream>
  12. #include <string>
  13. #include <vector>
  14.  
  15. namespace Algorithms {
  16. struct CRCResult {
  17.   std::string inputBits;
  18.   std::string checksum;
  19. };
  20.  
  21. struct HammingResult {
  22.   std::string inputBits;
  23.   std::string inputBitsWithControlBits;
  24.   int controlBitsAmount;
  25.   int dataBitsAmount;
  26.   double dataControlRatio;
  27.   bool singleErrorCorrected;
  28.   bool doubleErrorDetected;
  29. };
  30.  
  31. template <typename T>
  32. inline std::string _checksum_to_string(T checksum) {
  33.   std::stringstream checksumStrStream;
  34.  
  35.   checksumStrStream << "0x" << std::hex << checksum;
  36.  
  37.   return checksumStrStream.str();
  38. }
  39.  
  40. inline char _xor(char a, char b) {
  41.   if (a == b) {
  42.     return '0';
  43.   }
  44.   return '1';
  45. }
  46.  
  47. template <typename MutIt, typename ConstIt>
  48. inline void _xor_poly(MutIt bits, ConstIt poly, std::size_t length) {
  49.   for (std::size_t i = 0; i < length; i++) {
  50.     *bits = _xor(*bits, *poly);
  51.     bits++;
  52.     poly++;
  53.   }
  54. }
  55.  
  56. // Bits - data bits in string for, for example "100010101"
  57. // Poly - CRC polynomial in bits form, for example "1011"
  58. // Filler - filler char, either '0' or '1'
  59. CRCResult crc(std::string const& bits, std::string const& poly, char filler) {
  60.   CRCResult result{};
  61. #ifdef DEBUG_PRINTS_ENABLED
  62.   QTextStream out(stdout);
  63.  
  64.   out << "Input bits: " << QString::fromStdString(bits)
  65.       << ", poly: " << QString::fromStdString(poly) << " filler: " << filler
  66.       << '\n';
  67. #endif
  68.  
  69.   // Step 1: create working string from data bits, right-padded with filler
  70.   std::string padded_bits = bits + std::string(poly.length() - 1, filler);
  71. #ifdef DEBUG_PRINTS_ENABLED
  72.   out << "Padded input bits: " << QString::fromStdString(padded_bits) << "\n";
  73.   out.flush();
  74. #endif
  75.  
  76.   // Step 2: loop over the padded bits, and perform XOR with poly
  77.   auto it = padded_bits.begin();
  78. #ifdef DEBUG_PRINTS_ENABLED
  79.   out << QString::fromStdString(padded_bits) << '\n';
  80. #endif
  81.   for (std::size_t i = 0; i < bits.length(); i++) {
  82.     // If the MSB is not 1, continue
  83.     if (*it == '0') {
  84.       it++;
  85.       continue;
  86.     }
  87.  
  88. #ifdef DEBUG_PRINTS_ENABLED
  89.     out << QString(i, ' ') << QString::fromStdString(poly) << '\n';
  90.     out << QString(padded_bits.length(), '-') << '\n';
  91.     out.flush();
  92. #endif
  93.  
  94.     // XOR over the poly
  95.     _xor_poly(it, poly.cbegin(), poly.length());
  96. #ifdef DEBUG_PRINTS_ENABLED
  97.     out << QString::fromStdString(padded_bits) << '\n';
  98. #endif
  99.     it++;
  100.   }
  101.  
  102. #ifdef DEBUG_PRINTS_ENABLED
  103.   out << "Final result: " << QString::fromStdString(padded_bits) << '\n';
  104.   out.flush();
  105. #endif
  106.  
  107.   // Step 3: take the checksum from data string and convert it to hex string
  108.   std::string const checksum_binary_str = padded_bits.substr(bits.length());
  109.   auto checksum_value = std::stoul(checksum_binary_str, nullptr, 2);
  110.  
  111.   result.inputBits = bits;
  112.   result.checksum = _checksum_to_string(checksum_value);
  113.  
  114.   return result;
  115. }
  116.  
  117. }  // namespace Algorithms
  118.  
RAW Paste Data