| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmBase32.h" |
| |
| // -- Static functions |
| |
| static const unsigned char Base32EncodeTable[33] = |
| "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; |
| |
| inline unsigned char Base32EncodeChar(int schar) |
| { |
| return Base32EncodeTable[schar]; |
| } |
| |
| static void Base32Encode5(const unsigned char src[5], char dst[8]) |
| { |
| // [0]:5 bits |
| dst[0] = Base32EncodeChar((src[0] >> 3) & 0x1F); |
| // [0]:3 bits + [1]:2 bits |
| dst[1] = Base32EncodeChar(((src[0] << 2) & 0x1C) + ((src[1] >> 6) & 0x03)); |
| // [1]:5 bits |
| dst[2] = Base32EncodeChar((src[1] >> 1) & 0x1F); |
| // [1]:1 bit + [2]:4 bits |
| dst[3] = Base32EncodeChar(((src[1] << 4) & 0x10) + ((src[2] >> 4) & 0x0F)); |
| // [2]:4 bits + [3]:1 bit |
| dst[4] = Base32EncodeChar(((src[2] << 1) & 0x1E) + ((src[3] >> 7) & 0x01)); |
| // [3]:5 bits |
| dst[5] = Base32EncodeChar((src[3] >> 2) & 0x1F); |
| // [3]:2 bits + [4]:3 bit |
| dst[6] = Base32EncodeChar(((src[3] << 3) & 0x18) + ((src[4] >> 5) & 0x07)); |
| // [4]:5 bits |
| dst[7] = Base32EncodeChar((src[4] << 0) & 0x1F); |
| } |
| |
| // -- Class methods |
| |
| cmBase32Encoder::cmBase32Encoder() = default; |
| |
| std::string cmBase32Encoder::encodeString(const unsigned char* input, |
| size_t len, bool padding) |
| { |
| std::string res; |
| |
| static const size_t blockSize = 5; |
| static const size_t bufferSize = 8; |
| char buffer[bufferSize]; |
| |
| const unsigned char* end = input + len; |
| while ((input + blockSize) <= end) { |
| Base32Encode5(input, buffer); |
| res.append(buffer, bufferSize); |
| input += blockSize; |
| } |
| |
| size_t remain = static_cast<size_t>(end - input); |
| if (remain != 0) { |
| // Temporary source buffer filled up with 0s |
| unsigned char extended[blockSize]; |
| for (size_t ii = 0; ii != remain; ++ii) { |
| extended[ii] = input[ii]; |
| } |
| for (size_t ii = remain; ii != blockSize; ++ii) { |
| extended[ii] = 0; |
| } |
| |
| Base32Encode5(extended, buffer); |
| size_t numPad(0); |
| switch (remain) { |
| case 1: |
| numPad = 6; |
| break; |
| case 2: |
| numPad = 4; |
| break; |
| case 3: |
| numPad = 3; |
| break; |
| case 4: |
| numPad = 1; |
| break; |
| default: |
| break; |
| } |
| res.append(buffer, bufferSize - numPad); |
| if (padding) { |
| for (size_t ii = 0; ii != numPad; ++ii) { |
| res.push_back(paddingChar); |
| } |
| } |
| } |
| |
| return res; |
| } |