cmBase32.cxx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. 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. cmBase32Encoder::~cmBase32Encoder() = default;
  33. std::string cmBase32Encoder::encodeString(const unsigned char* input,
  34. size_t len, bool padding)
  35. {
  36. std::string res;
  37. static const size_t blockSize = 5;
  38. static const size_t bufferSize = 8;
  39. char buffer[bufferSize];
  40. const unsigned char* end = input + len;
  41. while ((input + blockSize) <= end) {
  42. Base32Encode5(input, buffer);
  43. res.append(buffer, bufferSize);
  44. input += blockSize;
  45. }
  46. size_t remain = static_cast<size_t>(end - input);
  47. if (remain != 0) {
  48. // Temporary source buffer filled up with 0s
  49. unsigned char extended[blockSize];
  50. for (size_t ii = 0; ii != remain; ++ii) {
  51. extended[ii] = input[ii];
  52. }
  53. for (size_t ii = remain; ii != blockSize; ++ii) {
  54. extended[ii] = 0;
  55. }
  56. Base32Encode5(extended, buffer);
  57. size_t numPad(0);
  58. switch (remain) {
  59. case 1:
  60. numPad = 6;
  61. break;
  62. case 2:
  63. numPad = 4;
  64. break;
  65. case 3:
  66. numPad = 3;
  67. break;
  68. case 4:
  69. numPad = 1;
  70. break;
  71. default:
  72. break;
  73. }
  74. res.append(buffer, bufferSize - numPad);
  75. if (padding) {
  76. for (size_t ii = 0; ii != numPad; ++ii) {
  77. res.push_back(paddingChar);
  78. }
  79. }
  80. }
  81. return res;
  82. }