base64.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #ifndef BASE64_H
  2. #define BASE64_H
  3. #include <string>
  4. namespace bzbstring {
  5. const std::string BASE64_MIME_CHARS =
  6. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  7. /*
  8. * Encode a string in Base64 MIME format
  9. */
  10. inline std::string base64_encode(const std::string &str,
  11. const std::string characters = BASE64_MIME_CHARS) {
  12. std::string string_encoded;
  13. const size_t str_len = str.size();
  14. size_t index = 0;
  15. while (index < str_len) {
  16. uint8_t ch1 = str[index];
  17. uint8_t ch2 = ((index + 1) < str_len) ? str[index + 1] : 0;
  18. uint8_t ch3 = ((index + 2) < str_len) ? str[index + 2] : 0;
  19. uint8_t ch1_temp = (ch1 >> 0x02);
  20. uint8_t ch2_temp = ((ch1 & 0x03) << 0x04) | (ch2 >> 0x04);
  21. uint8_t ch3_temp = ((ch2 & 0x0F) << 0x02) | (ch3 >> 0x06);
  22. uint8_t ch4_temp = (ch3 & 0x3F);
  23. string_encoded += characters[ch1_temp];
  24. string_encoded += characters[ch2_temp];
  25. string_encoded += characters[ch3_temp];
  26. string_encoded += characters[ch4_temp];
  27. index += 3;
  28. }
  29. size_t padding;
  30. if (str_len % 3 == 0) {
  31. padding = 0;
  32. } else if (str_len % 3 == 1) {
  33. padding = 2;
  34. } else {
  35. padding = 1;
  36. }
  37. string_encoded.erase(string_encoded.end() - padding, string_encoded.end());
  38. while (padding--)
  39. string_encoded.append("=");
  40. return string_encoded;
  41. }
  42. /*
  43. * Decode a string in Base64 MIME format
  44. */
  45. inline std::string base64_decode(const std::string &str,
  46. const std::string characters = BASE64_MIME_CHARS) {
  47. unsigned int ch1_code;
  48. unsigned int ch2_code;
  49. unsigned int ch3_code;
  50. std::string string_decoded;
  51. const size_t str_len = str.size();
  52. size_t index = 0;
  53. while (index < str_len) {
  54. long int index1_temp = characters.find_first_of(str[index + 0]);
  55. long int index2_temp = characters.find_first_of(str[index + 1]);
  56. long int index3_temp = characters.find_first_of(str[index + 2]);
  57. long int index4_temp = characters.find_first_of(str[index + 3]);
  58. if( index1_temp < -1 ||
  59. index2_temp < -1 ||
  60. index3_temp < -1 ||
  61. index4_temp < -1) {
  62. return "";
  63. }
  64. // First char code
  65. ch1_code = index1_temp << 0x02 | index2_temp >> 0x04;
  66. string_decoded += static_cast<char>(ch1_code);
  67. if (index3_temp & 0x80 || index4_temp & 0x80)
  68. break; // char not found (ie. '=', or not valid char)
  69. // Second char code
  70. ch2_code = (index2_temp << 0x04) | (index3_temp >> 0x02);
  71. string_decoded += static_cast<char>(ch2_code);
  72. // Third char code
  73. ch3_code = (index3_temp & 0x03) << 0x06 | (index4_temp & 0x3F);
  74. string_decoded += static_cast<char>(ch3_code);
  75. index += 4;
  76. }
  77. return string_decoded;
  78. }
  79. }
  80. #endif