cmBase32.cxx 2.4 KB

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