cmBase32.cxx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmBase32.h"
  4. // -- Static functions
  5. static const unsigned char Base32EncodeTable[33] =
  6. "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
  7. inline unsigned char Base32EncodeChar(int schar)
  8. {
  9. return Base32EncodeTable[schar];
  10. }
  11. static void Base32Encode5(const unsigned char src[5], char dst[8])
  12. {
  13. // [0]:5 bits
  14. dst[0] = Base32EncodeChar((src[0] >> 3) & 0x1F);
  15. // [0]:3 bits + [1]:2 bits
  16. dst[1] = Base32EncodeChar(((src[0] << 2) & 0x1C) + ((src[1] >> 6) & 0x03));
  17. // [1]:5 bits
  18. dst[2] = Base32EncodeChar((src[1] >> 1) & 0x1F);
  19. // [1]:1 bit + [2]:4 bits
  20. dst[3] = Base32EncodeChar(((src[1] << 4) & 0x10) + ((src[2] >> 4) & 0x0F));
  21. // [2]:4 bits + [3]:1 bit
  22. dst[4] = Base32EncodeChar(((src[2] << 1) & 0x1E) + ((src[3] >> 7) & 0x01));
  23. // [3]:5 bits
  24. dst[5] = Base32EncodeChar((src[3] >> 2) & 0x1F);
  25. // [3]:2 bits + [4]:3 bit
  26. dst[6] = Base32EncodeChar(((src[3] << 3) & 0x18) + ((src[4] >> 5) & 0x07));
  27. // [4]:5 bits
  28. dst[7] = Base32EncodeChar((src[4] << 0) & 0x1F);
  29. }
  30. // -- Class methods
  31. cmBase32Encoder::cmBase32Encoder() = default;
  32. std::string cmBase32Encoder::encodeString(const unsigned char* input,
  33. size_t len, bool padding)
  34. {
  35. std::string res;
  36. static const size_t blockSize = 5;
  37. static const size_t bufferSize = 8;
  38. char buffer[bufferSize];
  39. const unsigned char* end = input + len;
  40. while ((input + blockSize) <= end) {
  41. Base32Encode5(input, buffer);
  42. res.append(buffer, bufferSize);
  43. input += blockSize;
  44. }
  45. size_t remain = static_cast<size_t>(end - input);
  46. if (remain != 0) {
  47. // Temporary source buffer filled up with 0s
  48. unsigned char extended[blockSize];
  49. for (size_t ii = 0; ii != remain; ++ii) {
  50. extended[ii] = input[ii];
  51. }
  52. for (size_t ii = remain; ii != blockSize; ++ii) {
  53. extended[ii] = 0;
  54. }
  55. Base32Encode5(extended, buffer);
  56. size_t numPad(0);
  57. switch (remain) {
  58. case 1:
  59. numPad = 6;
  60. break;
  61. case 2:
  62. numPad = 4;
  63. break;
  64. case 3:
  65. numPad = 3;
  66. break;
  67. case 4:
  68. numPad = 1;
  69. break;
  70. default:
  71. break;
  72. }
  73. res.append(buffer, bufferSize - numPad);
  74. if (padding) {
  75. for (size_t ii = 0; ii != numPad; ++ii) {
  76. res.push_back(paddingChar);
  77. }
  78. }
  79. }
  80. return res;
  81. }