microsoft/onnxruntime-extensions
Publicmirrored fromhttps://github.com/microsoft/onnxruntime-extensionsAvailable
base/base64.cc
93lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | // Licensed under the MIT License. |
| 3 | #include "base64.h" |
| 4 | #include <stdexcept> |
| 5 | |
| 6 | const static std::string encodeLookup("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); |
| 7 | const static char padCharacter = '='; |
| 8 | |
| 9 | bool base64_encode(const std::vector<uint8_t>& input, std::string& encoded) { |
| 10 | encoded.clear(); |
| 11 | encoded.reserve(((input.size() / 3) + (input.size() % 3 > 0)) * 4); |
| 12 | uint32_t temp; |
| 13 | std::vector<uint8_t>::const_iterator cursor = input.begin(); |
| 14 | for (size_t idx = 0; idx < input.size() / 3; idx++) { |
| 15 | temp = (*cursor++) << 16; //Convert to big endian |
| 16 | temp += (*cursor++) << 8; |
| 17 | temp += (*cursor++); |
| 18 | encoded.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]); |
| 19 | encoded.append(1, encodeLookup[(temp & 0x0003F000) >> 12]); |
| 20 | encoded.append(1, encodeLookup[(temp & 0x00000FC0) >> 6]); |
| 21 | encoded.append(1, encodeLookup[(temp & 0x0000003F)]); |
| 22 | } |
| 23 | switch (input.size() % 3) { |
| 24 | case 1: |
| 25 | temp = (*cursor++) << 16; |
| 26 | encoded.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]); |
| 27 | encoded.append(1, encodeLookup[(temp & 0x0003F000) >> 12]); |
| 28 | encoded.append(2, padCharacter); |
| 29 | break; |
| 30 | case 2: |
| 31 | temp = (*cursor++) << 16; |
| 32 | temp += (*cursor++) << 8; |
| 33 | encoded.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]); |
| 34 | encoded.append(1, encodeLookup[(temp & 0x0003F000) >> 12]); |
| 35 | encoded.append(1, encodeLookup[(temp & 0x00000FC0) >> 6]); |
| 36 | encoded.append(1, padCharacter); |
| 37 | break; |
| 38 | } |
| 39 | encoded = encoded; |
| 40 | return true; |
| 41 | } |
| 42 | |
| 43 | bool base64_decode(const std::string& input, std::vector<uint8_t>& decoded) { |
| 44 | if (input.length() % 4) |
| 45 | return false; |
| 46 | size_t padding = 0; |
| 47 | if (input.length()) { |
| 48 | if (input[input.length() - 1] == padCharacter) |
| 49 | padding++; |
| 50 | if (input[input.length() - 2] == padCharacter) |
| 51 | padding++; |
| 52 | } |
| 53 | |
| 54 | decoded.clear(); |
| 55 | decoded.reserve(((input.length() / 4) * 3) - padding); |
| 56 | uint32_t temp = 0; |
| 57 | std::string::const_iterator cursor = input.begin(); |
| 58 | size_t quantumPosition; |
| 59 | while (cursor != input.end()) { |
| 60 | for (quantumPosition = 0; quantumPosition < 4; ++quantumPosition) { |
| 61 | temp <<= 6; |
| 62 | if (*cursor >= 0x41 && *cursor <= 0x5A) |
| 63 | temp |= *cursor - 0x41; |
| 64 | else if (*cursor >= 0x61 && *cursor <= 0x7A) |
| 65 | temp |= *cursor - 0x47; |
| 66 | else if (*cursor >= 0x30 && *cursor <= 0x39) |
| 67 | temp |= *cursor + 0x04; |
| 68 | else if (*cursor == 0x2B) |
| 69 | temp |= 0x3E; |
| 70 | else if (*cursor == 0x2F) |
| 71 | temp |= 0x3F; |
| 72 | else if (*cursor == padCharacter) { |
| 73 | switch (input.end() - cursor) { |
| 74 | case 1: //One pad character |
| 75 | decoded.push_back((temp >> 16) & 0x000000FF); |
| 76 | decoded.push_back((temp >> 8) & 0x000000FF); |
| 77 | return true; |
| 78 | case 2: //Two pad characters |
| 79 | decoded.push_back((temp >> 10) & 0x000000FF); |
| 80 | return true; |
| 81 | default: |
| 82 | return false; |
| 83 | } |
| 84 | } else |
| 85 | return false; |
| 86 | ++cursor; |
| 87 | } |
| 88 | decoded.push_back((temp >> 16) & 0x000000FF); |
| 89 | decoded.push_back((temp >> 8) & 0x000000FF); |
| 90 | decoded.push_back((temp)&0x000000FF); |
| 91 | } |
| 92 | return true; |
| 93 | } |
| 94 | |