11
Apr
2013
Base64加密解密算法的C/C++代码实现
今天再次用到了base64编解码,以前看过,现在又有点陌生了,上网查了下,然后用c++实现了下,在此记录下,以备将来查用。
介绍
用途
Base64算法不是为了防止内容被人破解而使用的算法, 因为破解Base64太容易了, 就是简单的字符替换。 Base64还有个不好的地方,就是加密后, 长度会变成。 那我们为何还要使用Base64 呢?因为Base64可以把乱七八糟的二进制转化为字符串,这个特性在很多地方很有用。
实现(c++)
// Base64.h
#ifndef __BASE64_H__
#define __BASE64_H__
#include <string>
using std::string;
class CBase64
{
public:
static bool Encode(const string& strIn,string& strOut);
static bool Decode(const string& strIn,string& strOut,bool fCheckInputValid = false);
};
#endif
// Base64.cpp
#include "base64.h"
static const char encode_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char decode_map[256];
static void initBase64DecodeMap()
{
memset(decode_map,-1,sizeof(decode_map));
for (int i = 'A'; i <= 'Z'; ++i) decode_map[i] = 0 + (i - 'A');
for (int i = 'a'; i <= 'z'; ++i) decode_map[i] = 26 + (i - 'a');
for (int i = '0'; i <= '9'; ++i) decode_map[i] = 52 + (i - '0');
decode_map[(unsigned char)'+'] = 62;
decode_map[(unsigned char)'/'] = 63;
decode_map[(unsigned char)'='] = 0;
}
bool CBase64::Encode(const string& strIn,string& strOut)
{
size_t nInLen = strIn.length();
size_t numOrig24BitValues = nInLen/3;
bool havePadding = (nInLen != numOrig24BitValues*3);
bool havePadding2 = (nInLen == numOrig24BitValues*3 + 1);
size_t numResultBytes = 4*(numOrig24BitValues + havePadding);
strOut.clear();
for (size_t i = 0; i < numOrig24BitValues; ++i)
{
strOut.append(1,encode_map[(strIn[3*i] >> 2) & 0x3F]);
strOut.append(1,encode_map[((strIn[3*i] << 4) & 0x30) | ((strIn[3*i+1] >> 4) & 0x0F)]);
strOut.append(1,encode_map[((strIn[3*i+1] << 2) & 0x3C) | ((strIn[3*i+2] >> 6) & 0x03)]);
strOut.append(1,encode_map[strIn[3*i+2] & 0x3F]);
}
if (havePadding)
{
size_t i = numOrig24BitValues;
strOut.append(1,encode_map[(strIn[3*i] >> 2) & 0x3F]);
if (havePadding2)
{
strOut.append(1,encode_map[((strIn[3*i] << 4) & 0x30) | ((strIn[3*i+1] >> 4) & 0x0F)]);
strOut.append(1,'=');
}
else
{
strOut.append(1,encode_map[((strIn[3*i] << 4) & 0x30) | ((strIn[3*i+1] >> 4) & 0x0F)]);
strOut.append(1,encode_map[((strIn[3*i+1] << 2) & 0x3C) | ((strIn[3*i+2] >> 6) & 0x03)]);
}
strOut.append(1,'=');
}
return true;
}
bool CBase64::Decode(const string& strIn,string& strOut,bool fCheckInputValid/* = false*/)
{
size_t nInlen = strIn.length();
if (nInlen < 4 || (nInlen % 4) != 0)
{
return false;
}
static bool bInit = false;
if (!bInit)
{
initBase64DecodeMap();
bInit = true;
}
if (fCheckInputValid)
{
for (size_t i = 0; i < nInlen; ++i)
{
if (decode_map[(unsigned char)strIn[i]] == -1)
{
return false;
}
}
}
size_t nOutLen = (nInlen * 3) / 4;
string strTmpOut;
strTmpOut.resize(nOutLen);
size_t nLoopLen = nOutLen / 3;
for (size_t i = 0; i < nLoopLen;++i)
{
strTmpOut[i*3] = ((decode_map[strIn[i*4]] << 2) & 0xFC) | ((decode_map[strIn[i*4+1]] >> 4) & 0x03);
strTmpOut[i*3+1] = ((decode_map[strIn[i*4+1]] << 4) & 0xF0) | ((decode_map[strIn[i*4+2]] >> 2) & 0x0F);
strTmpOut[i*3+2] = ((decode_map[strIn[i*4+2]] << 6) & 0xC0) | (decode_map[strIn[i*4+3]] & 0x3F);
}
if (strIn[nInlen - 1] == '=')
{
nOutLen--;
if (strIn[nInlen - 2] == '=')
{
nOutLen--;
}
}
const char* pData = strTmpOut.data();
strOut.clear();
strOut.append(pData,pData + nOutLen);
return true;
}
获取
获取文件及更新:Github
PS: 在电子邮件中,根据RFC 822规定,每76个字符,还需要加上一个回车换行。这个是MIME中的规定,base64只是一种编码格式,并不是所有的应用都需要遵守这个原则。
上一篇: 推倒重来,开始写blog
上一篇: Linux 文件权限