base64.cc 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include "util.h"
  2. #include <array>
  3. #include <functional>
  4. #include <algorithm>
  5. namespace hdfs {
  6. std::string Base64Encode(const std::string &src) {
  7. static const char kDictionary[] =
  8. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  9. "abcdefghijklmnopqrstuvwxyz"
  10. "0123456789+/";
  11. int encoded_size = (src.size() + 2) / 3 * 4;
  12. std::string dst;
  13. dst.reserve(encoded_size);
  14. size_t i = 0;
  15. while (i + 3 < src.length()) {
  16. const char *s = &src[i];
  17. const int r[4] = {
  18. s[0] >> 2,
  19. ((s[0] << 4) | (s[1] >> 4)) & 0x3f,
  20. ((s[1] << 2) | (s[2] >> 6)) & 0x3f,
  21. s[2] & 0x3f };
  22. std::transform(r, r + sizeof(r) / sizeof(int), std::back_inserter(dst),
  23. [&r](unsigned char v) { return kDictionary[v]; });
  24. i += 3;
  25. }
  26. size_t remained = src.length() - i;
  27. const char *s = &src[i];
  28. switch (remained) {
  29. case 0:
  30. break;
  31. case 1: {
  32. char padding[4] = {
  33. kDictionary[s[0] >> 2],
  34. kDictionary[(s[0] << 4) & 0x3f],
  35. '=', '=' };
  36. dst.append(padding, sizeof(padding));
  37. }
  38. break;
  39. case 2: {
  40. char padding[4] = {
  41. kDictionary[src[i] >> 2],
  42. kDictionary[((s[0] << 4) | (s[1] >> 4)) & 0x3f],
  43. kDictionary[(s[1] << 2) & 0x3f],
  44. '=' };
  45. dst.append(padding, sizeof(padding));
  46. }
  47. break;
  48. default:
  49. assert("Unreachable");
  50. break;
  51. }
  52. return dst;
  53. }
  54. }