Advertisement
Toliak

dz2

Nov 4th, 2018
397
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.64 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <iomanip>
  5. #include <bitset>
  6.  
  7. typedef unsigned char Byte;
  8. typedef unsigned __int16 Block;
  9.  
  10. static int SHIFT = 1;
  11. static int ENCRYPT_WAY = 1;
  12. static int HUMAN_OUTPUT = 1;
  13.  
  14. // Contains data (2 Bytes)
  15. // Can be circle-shifted, XORed and compared
  16. struct CircularData
  17. {
  18.     friend CircularData operator>>(CircularData l, int n);
  19.     friend CircularData operator<<(CircularData l, int n);
  20.     friend CircularData operator^(CircularData l, Block r);
  21.     friend bool operator==(CircularData l, CircularData r);
  22.  
  23.     Block data = 0;
  24. };
  25.  
  26. // Circle-shift
  27. CircularData operator>>(CircularData l, int n)
  28. {
  29.     Block mask = 0x0;
  30.     for (int i = 0; i < n; i++) {
  31.         mask <<= 1;
  32.         mask |= 1;
  33.     }
  34.     Block cycle = (l.data & mask) << (16 - n);      // Save right N bits
  35.  
  36.     return CircularData({
  37.                             static_cast<Block>((l.data >> n) | cycle)
  38.                         });     // Default shift and append saved bits
  39. }
  40.  
  41. CircularData operator<<(CircularData l, int n)
  42. {
  43.     Block mask = 0x0;
  44.     for (int i = 0; i < n; i++) {
  45.         mask <<= 1;
  46.         mask |= 1;
  47.     }
  48.     Block cycle = (l.data >> (16 - n)) & mask;      // Save left N bits
  49.  
  50.     return CircularData({
  51.                             static_cast<Block>((l.data << n) | cycle)
  52.                         });     // Default shift and append saved bits
  53. }
  54.  
  55. CircularData operator^(CircularData l, Block r)
  56. {
  57.     return CircularData({
  58.                             static_cast<Block>(l.data ^ r)
  59.                         });     // Just XOR
  60. }
  61.  
  62. bool operator==(CircularData l, CircularData r)
  63. {
  64.     return l.data == r.data;
  65. }
  66.  
  67. // Output for vector of CircularData
  68. std::ostream &operator<<(std::ostream &s, const std::vector<CircularData> &v)
  69. {
  70.     for (auto &it : v) {
  71.         Block data = it.data;
  72.         s << static_cast<char>(data >> 8) << static_cast<char>(static_cast<Block>(data << 8) >> 8);
  73.     }
  74.     return s;
  75. }
  76.  
  77. // Encrypt data
  78. void encrypt(CircularData *data, Block salt)
  79. {
  80.     if (ENCRYPT_WAY == 0) {
  81.         (*data) = (*data ^ salt) << SHIFT;
  82.     } else {
  83.         (*data) = (*data ^ salt) >> SHIFT;
  84.     }
  85. }
  86.  
  87. // Decrypt data
  88. // (var ^ v) ^ v == var
  89. void decrypt(CircularData *data, Block salt)
  90. {
  91.     if (ENCRYPT_WAY == 0) {
  92.         (*data) = (*data >> SHIFT) ^ salt;
  93.     } else {
  94.         (*data) = (*data << SHIFT) ^ salt;
  95.     }
  96. }
  97.  
  98. int main(int argc, char *argv[])
  99. {
  100.     // For tests
  101.     if (argc >= 3) {
  102.         ENCRYPT_WAY = atoi(argv[1]);
  103.         SHIFT = atoi(argv[2]);
  104.         if (argc >= 4)
  105.             HUMAN_OUTPUT = atoi(argv[3]);
  106.     }
  107.     if (HUMAN_OUTPUT) {
  108.         std::cout << "Way         : " << (ENCRYPT_WAY == 0 ? "<<" : ">>") << std::endl;
  109.         std::cout << "Shift       : " << SHIFT << std::endl;
  110.     }
  111.  
  112.     std::string input;                      // String for encoding/decoding
  113.     if (HUMAN_OUTPUT)
  114.         std::cout << "Enter string: ";
  115.     std::getline(std::cin, input);
  116.  
  117.     std::vector<CircularData> data;         // Vector with 2 Byte elements
  118.     for (auto &c : input) {
  119.         static size_t index = 0;            // Current index
  120.         static Block block = 0;             // 2 Bytes block
  121.         if (index % 2 == 0) {
  122.             block = static_cast<Byte>(c) << 8;
  123.             if (index == input.size() - 1) {    // Save last char (if input size is odd)
  124.                 data.push_back({block});
  125.             }
  126.         } else {
  127.             block |= c;
  128.             data.push_back({block});        // Calling constructor with initializer-list
  129.         }
  130.         index++;
  131.     }
  132.  
  133.     std::string key;                // Will be used only 4 symbols
  134.     if (HUMAN_OUTPUT)
  135.         std::cout << "Enter key   : ";
  136.     std::getline(std::cin, key);
  137.  
  138.     // Include shift size and way in srand argument
  139.     Byte srandKeyPart = static_cast<Byte>(SHIFT) | static_cast<Byte>(ENCRYPT_WAY == 0) << 7;
  140.     unsigned int srandKey = (srandKeyPart ^ key[0]) << 24;      // Add first symbol
  141.     for (size_t i = 1; i < 4; i++) {            // Append 3 symbols to srandKey
  142.         auto current = static_cast<Byte>((key.size() > i) ? key[i] : '\0');
  143.         srandKey |= current << 8 * (3 - i);
  144.     }
  145.     srand(srandKey);                            // Apply key
  146.     auto salt = static_cast<Block>(rand());     // Generate salt
  147.  
  148.     for (auto &d : data)
  149.         encrypt(&d, salt);
  150.  
  151.     if (HUMAN_OUTPUT)
  152.         std::cout << "Encrypted   : ";
  153.     std::cout << data << std::endl;
  154.  
  155.     for (auto &d : data)
  156.         decrypt(&d, salt);
  157.  
  158.     if (HUMAN_OUTPUT)
  159.         std::cout << "Decrypted   : ";
  160.     std::cout << data << std::endl;
  161.  
  162.     return 0;
  163. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement