yukisaw

Base64 simple encoder

Dec 20th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.02 KB | None | 0 0
  1. //https://ru.wikipedia.org/wiki/Base64
  2.  
  3. #include <iostream>
  4. #include <memory>
  5. #include <array>
  6.  
  7. struct release_alloc { void operator()(void* p) const { free(p); } };
  8. std::unique_ptr<char, release_alloc> toB64(const void* mem, size_t len);
  9. std::unique_ptr<char, release_alloc> fromB64(const char* b64);
  10.  
  11. int main()
  12. {
  13.     std::string str = "Test string encoded to base64";
  14.    
  15.     auto str64 = toB64(str.data(), str.length());
  16.     std::cout << str64.get() << std::endl << std::endl;
  17.     std::cout << fromB64(str64.get()).get() << std::endl << std::endl;
  18.     system("pause");
  19.     return 0;
  20. }
  21.  
  22. std::array<char, 64> _B64 = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  23.                               'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  24.                               '0','1','2','3','4','5','6','7','8','9','+','/' };
  25.  
  26.  
  27.  
  28. std::unique_ptr<char, release_alloc> toB64(const void* mem, size_t len)
  29. {
  30.     std::unique_ptr<char, release_alloc> result((char*)malloc(len / 3 * 4 + (len % 3 ? 5 : 1)));
  31.     const char* source = (char*)mem;
  32.     char* dest = result.get();
  33.     char buf[3];
  34.     char index = 0;
  35.     for (; len > 0; --len)
  36.     {
  37.         buf[index++] = *(source++);
  38.         if (index == 3)
  39.         {
  40.             *(dest++) = _B64[(buf[0] & 0xfc) >> 2];
  41.             *(dest++) = _B64[((buf[0] & 0x03) << 4) + ((buf[1] & 0xf0) >> 4)];
  42.             *(dest++) = _B64[((buf[1] & 0x0f) << 2) + ((buf[2] & 0xc0) >> 6)];
  43.             *(dest++) = _B64[buf[2] & 0x3f];
  44.             index = 0;
  45.         }
  46.     }
  47.     if (index)
  48.     {
  49.         *(dest++) = _B64[(buf[0] & 0xfc) >> 2];
  50.         if (index == 1)
  51.         {
  52.             *(dest++) = _B64[((buf[0] & 0x03) << 4)];
  53.             *(dest++) = '='; *(dest++) = '=';
  54.         }
  55.         else
  56.         {
  57.             *(dest++) = _B64[((buf[0] & 0x03) << 4) + ((buf[1] & 0xf0) >> 4)];
  58.             *(dest++) = _B64[((buf[1] & 0x0f) << 2)];
  59.             *(dest++) = '=';
  60.         }
  61.     }
  62.     *(dest++) = 0;
  63.     return result;
  64. }
  65.  
  66.  
  67. std::array<unsigned char, 123> _R64 =
  68.         { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  69.           0,0,0,0,0,0,0,62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,
  70.           1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,
  71.           0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51 };
  72.  
  73. std::unique_ptr<char, release_alloc> fromB64(const char* b64)
  74. {
  75.     size_t len = strlen(b64);
  76.     std::unique_ptr<char, release_alloc> result((char*)malloc(len / 4 * 3));
  77.     unsigned char* dest = (unsigned char*)result.get();
  78.     char buf[4];
  79.     char index = 0;
  80.     while (*b64 && *b64 != '=')
  81.     {
  82.         buf[index++] = *(b64++);
  83.         if (index == 4)
  84.         {
  85.             int pos1 = _R64[buf[0]], pos2 = _R64[buf[1]];
  86.  
  87.             *(dest++) = (_R64[buf[0]] << 2) | (_R64[buf[1]] >> 4);
  88.             *(dest++) = (_R64[buf[1]] << 4) | (_R64[buf[2]] >> 2);
  89.             *(dest++) = (_R64[buf[2]] << 6) | (_R64[buf[3]]);
  90.             index = 0;
  91.         }
  92.     }
  93.     if (index)
  94.     {
  95.         while (index != 4)
  96.             buf[index++] = 0;
  97.         *(dest++) = (_R64[buf[0]] << 2) | (_R64[buf[1]] >> 4);
  98.         *(dest++) = (_R64[buf[1]] << 4) | (_R64[buf[2]] >> 2);
  99.         *(dest++) = (_R64[buf[2]] << 6) | (_R64[buf[3]]);
  100.     }
  101.     return result;
  102. }
Advertisement
Add Comment
Please, Sign In to add comment