base64解码片段在c + +
任何人有一个免费的C + + base64解码代码片段?
Google是你的朋友
以下是该页面的实现:
/* base64.cpp and base64.h Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this source code must not be misrepresented; you must not claim that you wrote the original source code. If you use this source code in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original source code. 3. This notice may not be removed or altered from any source distribution. René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } std::string base64_decode(std::string const& encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; }
这是我最初由RenéNyffenegger编写的实现的修改。 为什么我要修改它? 那么,因为我不应该使用存储在std::string
对象中的二进制数据;)
base64.h :
#ifndef _BASE64_H_ #define _BASE64_H_ #include <vector> #include <string> typedef unsigned char BYTE; std::string base64_encode(BYTE const* buf, unsigned int bufLen); std::vector<BYTE> base64_decode(std::string const&); #endif
base64.cpp :
#include "base64.h" #include <iostream> static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(BYTE c) { return (isalnum(c) || (c == '+') || (c == '/')); } std::string base64_encode(BYTE const* buf, unsigned int bufLen) { std::string ret; int i = 0; int j = 0; BYTE char_array_3[3]; BYTE char_array_4[4]; while (bufLen--) { char_array_3[i++] = *(buf++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } std::vector<BYTE> base64_decode(std::string const& encoded_string) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; BYTE char_array_4[4], char_array_3[3]; std::vector<BYTE> ret; while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret.push_back(char_array_3[i]); i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); } return ret; }
用法如下:
std::vector<BYTE> myData; ... std::string encodedData = base64_encode(&myData[0], myData.size()); std::vector<BYTE> decodedData = base64_decode(encodedData);
我希望有人会发现这个答案有帮助^^
这里有几个片段。 然而,这是一个紧凑,高效,和c + + 11友好:
static std::string base64_encode(const std::string &in) { std::string out; int val=0, valb=-6; for (uchar c : in) { val = (val<<8) + c; valb += 8; while (valb>=0) { out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val>>valb)&0x3F]); valb-=6; } } if (valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val<<8)>>(valb+8))&0x3F]); while (out.size()%4) out.push_back('='); return out; } static std::string base64_decode(const std::string &in) { std::string out; std::vector<int> T(256,-1); for (int i=0; i<64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i; int val=0, valb=-8; for (uchar c : in) { if (T[c] == -1) break; val = (val<<6) + T[c]; valb += 6; if (valb>=0) { out.push_back(char((val>>valb)&0xFF)); valb-=8; } } return out; }
使用base -n mini lib,您可以执行以下操作:
some_data_t in[] { ... }; constexpr int len = sizeof(in)/sizeof(in[0]); std::string encoded; bn::encode_b64(in, in + len, std::back_inserter(encoded)); some_data_t out[len]; bn::decode_b64(encoded.begin(), encoded.end(), out);
该API是通用的,基于迭代器的。
披露:我是作者。
我发现其他两个答案很难理解。 它们在我的编译器中也会产生一些警告,在解码部分中使用find函数会导致相当差的效率。 所以我决定推出自己的。
标题:
#ifndef _BASE64_H_ #define _BASE64_H_ #include <vector> #include <string> typedef unsigned char BYTE; class Base64 { public: static std::string encode(const std::vector<BYTE>& buf); static std::string encode(const BYTE* buf, unsigned int bufLen); static std::vector<BYTE> decode(std::string encoded_string); }; #endif
身体:
static const BYTE from_base64[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 62, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255}; static const char to_base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string Base64::encode(const std::vector<BYTE>& buf) { if (buf.empty()) return ""; // Avoid dereferencing buf if it's empty return encode(&buf[0], (unsigned int)buf.size()); } std::string Base64::encode(const BYTE* buf, unsigned int bufLen) { // Calculate how many bytes that needs to be added to get a multiple of 3 size_t missing = 0; size_t ret_size = bufLen; while ((ret_size % 3) != 0) { ++ret_size; ++missing; } // Expand the return string size to a multiple of 4 ret_size = 4*ret_size/3; std::string ret; ret.reserve(ret_size); for (unsigned int i=0; i<ret_size/4; ++i) { // Read a group of three bytes (avoid buffer overrun by replacing with 0) size_t index = i*3; BYTE b3[3]; b3[0] = (index+0 < bufLen) ? buf[index+0] : 0; b3[1] = (index+1 < bufLen) ? buf[index+1] : 0; b3[2] = (index+2 < bufLen) ? buf[index+2] : 0; // Transform into four base 64 characters BYTE b4[4]; b4[0] = ((b3[0] & 0xfc) >> 2); b4[1] = ((b3[0] & 0x03) << 4) + ((b3[1] & 0xf0) >> 4); b4[2] = ((b3[1] & 0x0f) << 2) + ((b3[2] & 0xc0) >> 6); b4[3] = ((b3[2] & 0x3f) << 0); // Add the base 64 characters to the return value ret.push_back(to_base64[b4[0]]); ret.push_back(to_base64[b4[1]]); ret.push_back(to_base64[b4[2]]); ret.push_back(to_base64[b4[3]]); } // Replace data that is invalid (always as many as there are missing bytes) for (size_t i=0; i<missing; ++i) ret[ret_size - i - 1] = '='; return ret; } std::vector<BYTE> Base64::decode(std::string encoded_string) { // Make sure string length is a multiple of 4 while ((encoded_string.size() % 4) != 0) encoded_string.push_back('='); size_t encoded_size = encoded_string.size(); std::vector<BYTE> ret; ret.reserve(3*encoded_size/4); for (size_t i=0; i<encoded_size; i += 4) { // Get values for each group of four base 64 characters BYTE b4[4]; b4[0] = (encoded_string[i+0] <= 'z') ? from_base64[encoded_string[i+0]] : 0xff; b4[1] = (encoded_string[i+1] <= 'z') ? from_base64[encoded_string[i+1]] : 0xff; b4[2] = (encoded_string[i+2] <= 'z') ? from_base64[encoded_string[i+2]] : 0xff; b4[3] = (encoded_string[i+3] <= 'z') ? from_base64[encoded_string[i+3]] : 0xff; // Transform into a group of three bytes BYTE b3[3]; b3[0] = ((b4[0] & 0x3f) << 2) + ((b4[1] & 0x30) >> 4); b3[1] = ((b4[1] & 0x0f) << 4) + ((b4[2] & 0x3c) >> 2); b3[2] = ((b4[2] & 0x03) << 6) + ((b4[3] & 0x3f) >> 0); // Add the byte to the return value if it isn't part of an '=' character (indicated by 0xff) if (b4[1] != 0xff) ret.push_back(b3[0]); if (b4[2] != 0xff) ret.push_back(b3[1]); if (b4[3] != 0xff) ret.push_back(b3[2]); } return ret; }
用法:
BYTE buf[] = "ABCD"; std::string encoded = Base64::encode(buf, 4); // encoded = "QUJDRA==" std::vector<BYTE> decoded = Base64::decode(encoded);
这里的一个好处是解码function也可以解码base 64编码的url变体。
我在@DaedalusAlpha答案的变化。 它避免了以一些testing为代价来复制参数。
使用uint8_t而不是BYTE。
添加一些方便的函数来处理string,虽然通常input数据是二进制的,并且可能有零字节,所以通常不应该作为string来操作(这通常意味着以null结尾的数据)。
还添加了一些强制修复编译器警告(至less在GCC上,我还没有通过MSVC运行)。
部分base64.hpp:
void base64_encode(string & out, const vector<uint8_t>& buf); void base64_encode(string & out, const uint8_t* buf, size_t bufLen); void base64_encode(string & out, string const& buf); void base64_decode(vector<uint8_t> & out, string const& encoded_string); // use this if you know the output should be a valid string void base64_decode(string & out, string const& encoded_string);
base64.cpp:
static const uint8_t from_base64[128] = { // 8 rows of 16 = 128 // note: only require 123 entries, as we only lookup for <= z , which z=122 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 62, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 0, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255 }; static const char to_base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; void base64_encode(string & out, string const& buf) { if (buf.empty()) base64_encode(out, NULL, 0); else base64_encode(out, reinterpret_cast<uint8_t const*>(&buf[0]), buf.size()); } void base64_encode(string & out, std::vector<uint8_t> const& buf) { if (buf.empty()) base64_encode(out, NULL, 0); else base64_encode(out, &buf[0], buf.size()); } void base64_encode(string & ret, uint8_t const* buf, size_t bufLen) { // Calculate how many bytes that needs to be added to get a multiple of 3 size_t missing = 0; size_t ret_size = bufLen; while ((ret_size % 3) != 0) { ++ret_size; ++missing; } // Expand the return string size to a multiple of 4 ret_size = 4*ret_size/3; ret.clear(); ret.reserve(ret_size); for (size_t i = 0; i < ret_size/4; ++i) { // Read a group of three bytes (avoid buffer overrun by replacing with 0) const size_t index = i*3; const uint8_t b3_0 = (index+0 < bufLen) ? buf[index+0] : 0; const uint8_t b3_1 = (index+1 < bufLen) ? buf[index+1] : 0; const uint8_t b3_2 = (index+2 < bufLen) ? buf[index+2] : 0; // Transform into four base 64 characters const uint8_t b4_0 = ((b3_0 & 0xfc) >> 2); const uint8_t b4_1 = ((b3_0 & 0x03) << 4) + ((b3_1 & 0xf0) >> 4); const uint8_t b4_2 = ((b3_1 & 0x0f) << 2) + ((b3_2 & 0xc0) >> 6); const uint8_t b4_3 = ((b3_2 & 0x3f) << 0); // Add the base 64 characters to the return value ret.push_back(to_base64[b4_0]); ret.push_back(to_base64[b4_1]); ret.push_back(to_base64[b4_2]); ret.push_back(to_base64[b4_3]); } // Replace data that is invalid (always as many as there are missing bytes) for (size_t i = 0; i != missing; ++i) ret[ret_size - i - 1] = '='; } template <class Out> void base64_decode_any( Out & ret, std::string const& in) { typedef typename Out::value_type T; // Make sure the *intended* string length is a multiple of 4 size_t encoded_size = in.size(); while ((encoded_size % 4) != 0) ++encoded_size; const size_t N = in.size(); ret.clear(); ret.reserve(3*encoded_size/4); for (size_t i = 0; i < encoded_size; i += 4) { // Note: 'z' == 122 // Get values for each group of four base 64 characters const uint8_t b4_0 = ( in[i+0] <= 'z') ? from_base64[static_cast<uint8_t>(in[i+0])] : 0xff; const uint8_t b4_1 = (i+1 < N and in[i+1] <= 'z') ? from_base64[static_cast<uint8_t>(in[i+1])] : 0xff; const uint8_t b4_2 = (i+2 < N and in[i+2] <= 'z') ? from_base64[static_cast<uint8_t>(in[i+2])] : 0xff; const uint8_t b4_3 = (i+3 < N and in[i+3] <= 'z') ? from_base64[static_cast<uint8_t>(in[i+3])] : 0xff; // Transform into a group of three bytes const uint8_t b3_0 = ((b4_0 & 0x3f) << 2) + ((b4_1 & 0x30) >> 4); const uint8_t b3_1 = ((b4_1 & 0x0f) << 4) + ((b4_2 & 0x3c) >> 2); const uint8_t b3_2 = ((b4_2 & 0x03) << 6) + ((b4_3 & 0x3f) >> 0); // Add the byte to the return value if it isn't part of an '=' character (indicated by 0xff) if (b4_1 != 0xff) ret.push_back( static_cast<T>(b3_0) ); if (b4_2 != 0xff) ret.push_back( static_cast<T>(b3_1) ); if (b4_3 != 0xff) ret.push_back( static_cast<T>(b3_2) ); } } void base64_decode(vector<uint8_t> & out, string const& encoded_string) { base64_decode_any(out, encoded_string); } void base64_decode(string & out, string const& encoded_string) { base64_decode_any(out, encoded_string); }
我认为这个更好用:
#include <string> #include <cstring> static const char* B64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const int B64index [256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; std::string b64encode(const void* data, const size_t len) { unsigned char* p = (unsigned char*)data; size_t d = len % 3; std::string str64(4 * (int(d > 0) + len / 3), '='); for (size_t i = 0, j = 0; i < len - d; i += 3) { int n = int(p[i]) << 16 | int(p[i + 1]) << 8 | p[i + 2]; str64[j++] = B64chars[n >> 18]; str64[j++] = B64chars[n >> 12 & 0x3F]; str64[j++] = B64chars[n >> 6 & 0x3F]; str64[j++] = B64chars[n & 0x3F]; } if (d--) /// padding { int n = d ? int(p[len - 2]) << 8 | p[len - 1] : p[len - 1]; str64[str64.size() - 2] = d ? B64chars[(n & 0xF) << 2] : '='; str64[str64.size() - 3] = d ? B64chars[n >> 4 & 0x03F] : B64chars[(n & 3) << 4]; str64[str64.size() - 4] = d ? B64chars[n >> 10] : B64chars[n >> 2]; } return str64; } std::string b64decode(const void* data, const size_t len) { unsigned char* p = (unsigned char*)data; int pad = len > 0 && (len % 4 || p[len - 1] == '='); const size_t L = ((len + 3) / 4 - pad) * 4; std::string str(L / 4 * 3 + pad, '\0'); for (size_t i = 0, j = 0; i < L; i += 4) { int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]]; str[j++] = n >> 16; str[j++] = n >> 8 & 0xFF; str[j++] = n & 0xFF; } if (pad) { int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12; str[str.size() - 1] = n >> 16; if (len > L + 2 && p[L + 2] != '=') { n |= B64index[p[L + 2]] << 6; str.push_back(n >> 8 & 0xFF); } } return str; } std::string b64decode(const std::string& str64) { return b64decode(str64.c_str(), str64.size()); }
感谢@Jens Alfke指出性能问题,我对这篇旧文章做了一些修改。 现在这个工作方式比以前更快了。 主要优点是,它也可以顺利处理损坏的数据。
一个更简洁的查找表和使用c + + 17function的一点变化:
std::string base64_decode(const std::string_view in) { // table from '+' to 'z' const uint8_t lookup[] = { 62, 255, 62, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 0, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; static_assert(sizeof(lookup) == 'z' - '+' + 1); std::string out; int val = 0, valb = -8; for (uint8_t c : in) { if (c < '+' || c > 'z') break; c -= '+'; if (lookup[c] >= 64) break; val = (val << 6) + lookup[c]; valb += 6; if (valb >= 0) { out.push_back(char((val >> valb) & 0xFF)); valb -= 8; } } return out; }
如果你没有std :: string_view,试试std :: experimental :: string_view。