Base64是一种基于64个可打印字符来表示二进制数据的表示方法,从本质上看Base64编码就是将三字节转四字节,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。
例:将 Man
base64编码
上面正好是3的倍数,如果数据的长度不是3的整数倍,就要在后面补0再计算,每补2个0就在Base64串后加上1个‘=’。
例:
#include
using namespace std;
//base64 encode
bool Base64EnCode(std::string strBase64, int nOldLen, std::string& strEnBase64, int& nEnLenth)
{
bool ret = true;
int len = nOldLen + nOldLen / 3 + 1;
char* decoded = new char[len];
boost::beast::detail::base64::encoded_size(nOldLen);
boost::beast::detail::base64::encode(decoded, strBase64.data(), nOldLen);
strEnBase64 = decoded;
nEnLenth = len;
return ret;
}
//base64 decode
bool Base64DeCode(std::string strEnBase64, int nEnLenth, std::string& strDeBase64, int& nDeLenth)
{
bool ret = true;
int len = nEnLenth * 3 / 4 + 1;
char* evcoded = new char[len];
boost::beast::detail::base64::decoded_size(nEnLenth);
boost::beast::detail::base64::decode(evcoded, strEnBase64.data(), nEnLenth);
strDeBase64 = evcoded;
nDeLenth = len;
return ret;
}
测试代码:
中间有个分字节打印,大家看运行结果会知道为啥我做这个操作。
char strin[128]="httpsdefas//asdasf:adsf1234q1";
string strout,strinb;
int outlen,inlen;
Base64EnCode(strin, strlen(strin), strout, outlen);
cout << strout.c_str() << endl;
int i = 0;
while (1)
{
if (i>= outlen)
break;
cout << strout[i] << endl;
i++;
}
char asd[128] = "";
memcpy(asd, (char*)strout.data(), outlen);
cout << asd << endl;
Base64DeCode(strout, strout.size(), strinb, inlen);
cout << strinb << endl;
结果:
在运行过程中,直接返回的string结果多了=�Q三个字符。原先,我直接使用memcpy赋值结果是正确的。我又去Base64EnCode
方法里面去做赋初值、置空、memset等操作,发现完全没用。于是,我写了个while将字符全打印出来发现又是正确的。这里只能看各位大佬的理解了,要是哪位大佬知道麻烦告知一下。
总结一下,测试的情况看,编码之后的结果是可以解析的。但是,不知道对方能否完全解析。要是要确保使用的结果,请在编码后在内存拷贝memcpy(asd, (char*)strout.data(), outlen);
下。
总体来说目标还是实现了的。
如果没有boost库,那么直接用这个把。也是验证过的
#ifndef __BASE64_H__
#define __BASE64_H__
#include
#include
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(const char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(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(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 = (int) 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;
}
#endif
参考文档:1、C/C++中使用Base64编码解码(使用boost
2、使用Boost库实现C++ Base64编解码