百科:https://baike.baidu.com/item/base64/8545775?fr=aladdin
1.自己写的解析方法:
class UTILS_API CBase64
{
public:
static std::string base64_encode(unsigned const char*, unsigned int len);
static std::string base64_decode(const std::string&s);
};
//base64编解码
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string CBase64::base64_encode(unsigned const char* 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 (int j = 0; j < 4; j++)
{
ret += base64_chars[char_array_4[j]];
}
i = 0;
}
}
//如果字符串不是3的整数倍,则会有剩余1个字节或2个字节的情况
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 CBase64::base64_decode(const std::string& 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] = static_cast<unsigned char>(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] = static_cast<unsigned char>(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;
}
2.使用ATL库:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <strsafe.h>
#include <atlenc.h>
#include <string>
#include <iostream>
int main()
{
std::wstring strMsg = L"1&13661901285&123456&WdpqZOLXJg3WZ0cEVhi687CQyAw722UuH4CRZXHQS91WVe9K48p08B2-pJ0Zl_M_gMs&&0&&2019-04-03 09:53:35&&";
size_t nLen = (strMsg.length() + 1) * 2;
wchar_t* lpszValue = (wchar_t*)_alloca(nLen);//在栈上分配内存,使用完毕,立即释放。
memcpy_s(lpszValue, nLen, strMsg.c_str(), nLen);
int nDstLen = nLen * 2 + 1;
char* pDstValue = new char[nDstLen];
memset(pDstValue, 0, nDstLen);
ATL::Base64Encode((const BYTE*)lpszValue, nLen, pDstValue, &nDstLen, ATL_BASE64_FLAG_NOCRLF);//编码
int nDstLen2 = 0;
BYTE* pDstValueDecode = NULL;
if (FALSE == ATL::Base64Decode(pDstValue, nDstLen, NULL, &nDstLen2))//获取目标字符串的长度
{
pDstValueDecode = new BYTE[nDstLen2 + 1];
memset(pDstValueDecode, 0, nDstLen2 + 1);
ATL::Base64Decode(pDstValue, nDstLen, pDstValueDecode, &nDstLen2);//解码
}
std::wstring ret = (wchar_t*)pDstValueDecode;
USES_CONVERSION;
std::string ret2 = W2A(ret.c_str());
delete[]pDstValue;
delete[]pDstValueDecode;
return 0;
}