这里提供2种base64编解码的实现方式:
- 通过纯C语言实现
- 基于OpenSSL的内的编解码组件
代码均是个人实战验证过的,可放心使用。
接口头文件#ifndef GL_BASE64_H #define GL_BASE64_H #include纯C语言实现cpp文件class GLBase64 { public: static std::string Encode(const std::string& src); static std::string Decode(const std::string& src); }; #endif // !GL_BASE64_H
#include "GLBase64.h" #include#include #include static int gl_b64idx(int c) { if (c < 26) { return c + 'A'; } else if (c < 52) { return c - 26 + 'a'; } else if (c < 62) { return c - 52 + '0'; } else { return c == 62 ? '+' : '/'; } } static int gl_b64rev(int c) { if (c >= 'A' && c <= 'Z') { return c - 'A'; } else if (c >= 'a' && c <= 'z') { return c + 26 - 'a'; } else if (c >= '0' && c <= '9') { return c + 52 - '0'; } else if (c == '+') { return 62; } else if (c == '/') { return 63; } else if (c == '=') { return 64; } else { return -1; } } int gl_base64_update(unsigned char ch, char* to, int n) { int rem = (n & 3) % 3; if (rem == 0) { to[n] = (char)gl_b64idx(ch >> 2); to[++n] = (char)((ch & 3) << 4); } else if (rem == 1) { to[n] = (char)gl_b64idx(to[n] | (ch >> 4)); to[++n] = (char)((ch & 15) << 2); } else { to[n] = (char)gl_b64idx(to[n] | (ch >> 6)); to[++n] = (char)gl_b64idx(ch & 63); n++; } return n; } int gl_base64_final(char* to, int n) { int saved = n; // printf("---[%.*s]n", n, to); if (n & 3) n = gl_base64_update(0, to, n); if ((saved & 3) == 2) n--; // printf(" %d[%.*s]n", n, n, to); while (n & 3) to[n++] = '='; to[n] = ' '; return n; } int gl_base64_encode(const unsigned char* p, int n, char* to) { int i, len = 0; for (i = 0; i < n; i++) len = gl_base64_update(p[i], to, len); len = gl_base64_final(to, len); return len; } int gl_base64_decode(const char* src, int n, char* dst) { const char* end = src + n; int len = 0; while (src + 3 < end) { int a = gl_b64rev(src[0]), b = gl_b64rev(src[1]), c = gl_b64rev(src[2]), d = gl_b64rev(src[3]); if (a == 64 || a < 0 || b == 64 || b < 0 || c < 0 || d < 0) return 0; dst[len++] = (char)((a << 2) | (b >> 4)); if (src[2] != '=') { dst[len++] = (char)((b << 4) | (c >> 2)); if (src[3] != '=') dst[len++] = (char)((c << 6) | d); } src += 4; } dst[len] = ' '; return len; } std::string GLBase64::Encode(const std::string& src) { if (src.empty()) return ""; int len = std::ceil(src.size() / 3.0) * 4 + 1; char* dst = new char[len]; memset(dst, 0, len); const unsigned char* pSrc = (const unsigned char*)&src[0]; gl_base64_encode(pSrc, src.size(), dst); std::string result(dst, strlen(dst)); delete[] dst; return result; } std::string GLBase64::Decode(const std::string& src) { if (src.empty()) return ""; size_t iSrcLen = src.size(); if (iSrcLen % 4 != 0) { std::cout << "input string error." << std::endl; return ""; } size_t len = iSrcLen / 4 * 3; char* dst = new char[len + 1]; memset(dst, 0, len + 1); len = gl_base64_decode((const char*)&src[0], iSrcLen, dst); std::string result(dst, len); delete[] dst; return result; }
基于OpenSSL的内的编解码组件实现注意:
这里的C语言实现是引用了mongoose(cesanta/mongoose: Embedded Web Server (github.com))的实现,他是基于GPL协议的,如果想将我分享的代码用于商业且不想开源,请慎重考虑。
#include "openssl/bio.h"
#include "openssl/buffer.h"
#include "openssl/evp.h"
// base64 编码
std::string GLBase64::Encode(const std::string& buffer)
{
BUF_MEM* bptr;
BIO* b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO* bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, buffer.data(), buffer.size());
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
BIO_set_close(b64, BIO_NOCLOSE);
std::string out;
out.resize(bptr->length);
memcpy(&out[0], bptr->data, bptr->length);
BIO_free_all(b64);
return out;
}
// base64 解码
std::string GLBase64::Decode(const std::string& input)
{
std::string out;
out.resize(input.size());
BIO* b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO* bmem = BIO_new_mem_buf(input.data(), input.size());
bmem = BIO_push(b64, bmem);
int len = BIO_read(bmem, &out[0], input.size());
BIO_free_all(bmem);
out.resize(len);
return out;
}
OpenSSL内部封装较好,所以代码比较短。在OpenSSL一统天下的年代,涉及网络安全访问,加解密的业务,没有几个公司是不用的。
如果,我的分享给您带来了帮助,别忘了给博主点赞+评论,大家的支持会促使我为大家分享更多的干货。



