Advertisement
Guest User

Untitled

a guest
Apr 16th, 2024
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.37 KB | None | 0 0
  1. #pragma warning(disable:4820)
  2. #pragma warning(disable:4668)
  3. #pragma warning(disable:4514)
  4. #pragma warning(disable:4710)
  5. #include <conio.h>
  6. #include <iostream>
  7. // *******************************************************
  8. #include <string>
  9.  
  10. char bit_extract(char const& byte, unsigned int const& index) {         // Extracts the bit from the byte "byte" at the position "index".
  11.     return ( (char) ( (unsigned int)byte << (24 + index) >> 31 ) );
  12. }
  13.  
  14. void bit_flip(char & byte, unsigned int const& index) {             // Flips the bit from the byte "byte" at the position "index".
  15.     byte ^= 0x0080 >> index;
  16. }
  17.  
  18. void swap(unsigned int & left, unsigned int & right) {
  19.     /*
  20.     left += right;
  21.     right = left - right;
  22.     left -= right;
  23.     */
  24.     left -= right = (left += right) - right;                // This crazy one-liner is equivalent with the previous 3 lines (that are commented).
  25. }
  26.  
  27. void array_sort_increasing(unsigned int *arr, unsigned int const& length) {
  28.     for (unsigned int left = 0; left <= length - 2; ++left) {
  29.         for (unsigned right = left + 1; right <= length - 1; ++right) {
  30.             if (arr[left] > arr[right]) {               // If comparation is true.
  31.                 swap(arr[left], arr[right]);            // Than arr[right] is the new minimum.
  32.             }
  33.         }
  34.     }
  35. }
  36.  
  37. void bit_insert(char &byte, unsigned int const &index, char const &BitVal) {    // Inserts the bit "BitVal" into the byte "byte" at the position "index".
  38.     if (BitVal == 0) {
  39.         byte &= 0xFF7F >> index;
  40.     }
  41.     else if (BitVal == 1) {
  42.         byte |= 0x0080 >> index;
  43.     }
  44. }
  45.  
  46. void perfect_encode(std::string const& message, std::string & result, unsigned int const& input_bits_number) {  // Bit i from "message" is gonna flip all bits from closed range: [i; i + half] from "result".
  47.     unsigned int is_range_odd = 0;                      // The range, from input, is of the form [i; i + half]. If this range is odd, than the bit, from output, on position (i + half) is gonna be flipped.
  48.     unsigned int const half_position = input_bits_number / 2;
  49.     for (unsigned int index = 0; index <= half_position; ++index) {
  50.         if (bit_extract(message[index / 8], index % 8)) {
  51.             is_range_odd = is_range_odd ^ 0x01;
  52.         }
  53.     }
  54.     if (is_range_odd) {
  55.         bit_flip(result[half_position / 8], half_position % 8);
  56.     }
  57.  
  58.     char LeftFromPair_VALUE, RightFromPair_VALUE;               // The pairs are of the form { i ; i + (half + 1) }.
  59.     unsigned int RightFromPair_POSITION = half_position + 1;
  60.     unsigned int LeftFromPair_POSITION;
  61.  
  62.     while (RightFromPair_POSITION != half_position) {
  63.         RightFromPair_VALUE = bit_extract(message[RightFromPair_POSITION / 8], RightFromPair_POSITION % 8);
  64.         LeftFromPair_POSITION = ((RightFromPair_POSITION - (half_position + 1)) + input_bits_number) % input_bits_number;
  65.         LeftFromPair_VALUE = bit_extract(message[LeftFromPair_POSITION / 8], LeftFromPair_POSITION % 8);
  66.  
  67.         if (LeftFromPair_VALUE != RightFromPair_VALUE) {        // When we move, inside input, from 1 range to the next range: we replace LeftFromPair_VALUE with RightFromPair_VALUE.
  68.             is_range_odd = is_range_odd ^ 0x01;
  69.         }
  70.         if (is_range_odd) {
  71.             bit_flip(result[RightFromPair_POSITION / 8], RightFromPair_POSITION % 8);
  72.         }
  73.         RightFromPair_POSITION = (RightFromPair_POSITION + 1) % input_bits_number;
  74.     }
  75. }
  76.  
  77. void perfect_decode(std::string const& output, std::string & input, unsigned int const& input_bits_number) {
  78.     input.resize(0);
  79.     unsigned int *FirstTeam = new unsigned int[input_bits_number];
  80.     FirstTeam[0] = 0;
  81.     unsigned int FirstTeam_COUNTER = 1;
  82.     bool previous_InputBit_position_TEAM = 0;
  83.     unsigned int *SecondTeam = new unsigned int[input_bits_number - 1];
  84.     unsigned int SecondTeam_COUNTER = 0;
  85.     unsigned int const half_position_plus_one = input_bits_number / 2 + 1;
  86.     unsigned int InputBit_position = half_position_plus_one;
  87.     while (InputBit_position) {
  88.         char OutputBit_value = bit_extract(output[InputBit_position / 8], InputBit_position % 8);
  89.         char PREV_OutputBit_value = bit_extract(output[(InputBit_position - 1) / 8], (InputBit_position - 1) % 8);
  90.  
  91.         if (OutputBit_value == PREV_OutputBit_value) {
  92.             if (previous_InputBit_position_TEAM == 0) {
  93.                 FirstTeam[FirstTeam_COUNTER] = InputBit_position;
  94.                 ++FirstTeam_COUNTER;
  95.             }
  96.             else {
  97.                 SecondTeam[SecondTeam_COUNTER] = InputBit_position;
  98.                 ++SecondTeam_COUNTER;
  99.             }
  100.         }
  101.         else {                              // OutputBit_value != PREV_OutputBit_value .
  102.             if (previous_InputBit_position_TEAM == 0) {
  103.                 SecondTeam[SecondTeam_COUNTER] = InputBit_position;
  104.                 ++SecondTeam_COUNTER;
  105.                 previous_InputBit_position_TEAM = 1;
  106.             }
  107.             else {
  108.                 FirstTeam[FirstTeam_COUNTER] = InputBit_position;
  109.                 ++FirstTeam_COUNTER;
  110.                 previous_InputBit_position_TEAM = 0;
  111.             }
  112.         }
  113.  
  114.         InputBit_position = (InputBit_position + half_position_plus_one) % input_bits_number;
  115.     }   // END while.
  116.     std::cout << "FirstTeam: ";
  117.     for (unsigned int i = 0; i < FirstTeam_COUNTER; ++i) {
  118.         std::cout << FirstTeam[i] << " ";
  119.     }
  120.     std::cout << "\nSecondTeam: ";
  121.     for (unsigned int i = 0; i < SecondTeam_COUNTER; ++i) {
  122.         std::cout << SecondTeam[i] << " ";
  123.     }
  124.     /*
  125.     std::cout << "\nAfter sorting ###\n";
  126.     array_sort_increasing(FirstTeam, FirstTeam_COUNTER);            // Sorting is NOT necessary !
  127.     array_sort_increasing(SecondTeam, SecondTeam_COUNTER);          // idem.
  128.     std::cout << "FirstTeam: ";
  129.     for (unsigned int i = 0; i < FirstTeam_COUNTER; ++i) {
  130.         std::cout << FirstTeam[i] << " ";
  131.     }
  132.     std::cout << "\nSecondTeam: ";
  133.     for (unsigned int i = 0; i < SecondTeam_COUNTER; ++i) {
  134.         std::cout << SecondTeam[i] << " ";
  135.     }
  136.     */
  137.     std::cout << "\n\n";
  138.     char belongs_first_InputRange = 0;
  139.     for (unsigned int i = 0; i < FirstTeam_COUNTER; ++i) {
  140.         if (FirstTeam[i] < half_position_plus_one) {            // If element 'i' from "FirstTeam" belongs inside [0 ; half_position] closed range (from input/message).
  141.             belongs_first_InputRange ^= 0x01;
  142.         }
  143.     }
  144.     char output_half_position_VALUE = bit_extract(output[(half_position_plus_one - 1) / 8], (half_position_plus_one - 1) % 8);
  145.     input.resize(input_bits_number / 8);
  146.  
  147.     if (output_half_position_VALUE == belongs_first_InputRange) {
  148.         std::cout << "FirstTeam is bit 1\n";
  149.         std::cout << "SecondTeam is bit 0\n";
  150.         for (unsigned int i = 0; i < FirstTeam_COUNTER; ++i) {
  151.             bit_insert(input[FirstTeam[i] / 8], FirstTeam[i] % 8, 1);       // insert '1' for each bit position from first team.
  152.         }
  153.         for (unsigned int i = 0; i < SecondTeam_COUNTER; ++i) {
  154.             bit_insert(input[SecondTeam[i] / 8], SecondTeam[i] % 8, 0);     // insert '0' for each bit position from second team.
  155.         }
  156.     }
  157.     else {
  158.         std::cout << "FirstTeam is bit 0\n";
  159.         std::cout << "SecondTeam is bit 1\n";
  160.         for (unsigned int i = 0; i < FirstTeam_COUNTER; ++i) {
  161.             bit_insert(input[FirstTeam[i] / 8], FirstTeam[i] % 8, 0);       // insert '0' for each bit position from first team.
  162.         }
  163.         for (unsigned int i = 0; i < SecondTeam_COUNTER; ++i) {             // insert '1' for each bit position from second team.
  164.             bit_insert(input[SecondTeam[i] / 8], SecondTeam[i] % 8, 1);
  165.         }
  166.     }
  167.  
  168.     delete[] FirstTeam;
  169.     delete[] SecondTeam;
  170. }
  171.  
  172. int main() {
  173.     std::cout << "no of bits inside input = ";
  174.     unsigned int input_bits_number;
  175.     std::cin >> input_bits_number;                      // "input_bits_number" must be: (power of 2) bits  AND at least 8 bits.
  176.     unsigned int const letter_no = input_bits_number / 8;
  177.     std::string message, result;
  178.     message.resize(letter_no);
  179.     result.resize(letter_no);
  180.     message[0] = static_cast<unsigned char>(0x62);
  181.     message[1] = static_cast<unsigned char>(0x1c);
  182.     message[2] = static_cast<unsigned char>(0x7c);
  183.     message[3] = static_cast<unsigned char>(0x76);
  184.     for (unsigned int i = 0; i < letter_no; ++i) {
  185.         result[i] = '\0';                       // '\0' <=> 0 <=> NULL.
  186.     }
  187.     perfect_encode(message, result, input_bits_number);
  188.     std::cout << "result: " << std::hex;
  189.     for (unsigned int i = 0; i < letter_no; ++i) {
  190.         if (static_cast<unsigned char>(result[i]) < 16) {
  191.             std::cout << '0';
  192.         }
  193.         std::cout << (int)static_cast<unsigned char>(result[i]);
  194.     }
  195.     std::cout << std::dec << '\n';
  196.     // -------------------------------------------------------      END ENcoding.
  197.     for (unsigned int i = 0; i < letter_no; ++i) {
  198.         message[i] = NULL;
  199.     }
  200.     perfect_decode(result, message, input_bits_number);
  201.     std::cout << "back to message: " << std::hex;
  202.     for (unsigned int i = 0; i < letter_no; ++i) {
  203.         if (static_cast<unsigned char>(message[i]) < 16) {
  204.             std::cout << "0";
  205.         }
  206.         std::cout << (int)static_cast<unsigned char>(message[i]);
  207.     }
  208.     std::cout << std::dec << '\n';
  209.     // -------------------------------------------------------      END DEcoding.
  210.     std::cout << "\n\nWaiting for any Key ...\n";
  211.     _getch();
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement