这里提供2种base64编解码的实现方式:
代码均是个人实战验证过的,可放心使用。
#ifndef GL_BASE64_H
#define GL_BASE64_H
#include
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] = '\0';
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] = '\0';
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;
}
注意:
这里的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一统天下的年代,涉及网络安全访问,加解密的业务,没有几个公司是不用的。
如果,我的分享给您带来了帮助,别忘了给博主点赞+评论,大家的支持会促使我为大家分享更多的干货。