2.解码
参考1:
// 从 data 还原 base64编码,解码的结果保存到 buffer
static void
decode_base64(uint8_t *buffer, uint16_t len, uint8_t *data)
{
uint8_t *bp = buffer; // bp 指向最近解出的码可以存放的位置
uint8_t *p = data; // p 指向 一组编码(四个) 的开头
uint8_t c1, c2, c3, c4; // 每次从 data 里获得 4 个编码存到c1 ~ c4
while (bp < buffer + len) { // 可保存解码的位置还没有超出缓冲区
c1 = CHAR64(*p); // 假设读取了 00aaaaaa 到 c1 (a表示 1 或 0)
c2 = CHAR64(*(p + 1)); // 假设读取了 00aabbbb 到 c2 (b表示 1 或 0)
if (c1 == 255 || c2 == 255)
break; // 如果遇到编码结束符 == 255 就退出解码过程
// 八位的c1左移两位,头六位成为解码的头部
// 用(00110000)截取八位的c2前半字节的后两位,右移四位,成为解码的尾部
*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4); // (aaaaaa00) | (000000aa)
if (bp >= buffer + len)
break; // 如果超出缓冲区,就退出本次解码过程
c3 = CHAR64(*(p + 2)); // 假设读取了 00bbbbcc 到 c3 (b 或 c 表示 1 或 0)
if (c3 == 255)
break; // 如果遇到编码结束符 == 255 就退出解码过程
// 用(00001111)截取八位的c2后半字节,左移四位,成为解码的头部
// 用(00111100)截取八位的c3中间四位,右移两位,成为解码的尾部
*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); // (bbbb0000) | (0000bbbb)
if (bp >= buffer + len)
break; // 如果超出缓冲区,就退出本次解码过程
c4 = CHAR64(*(p + 3)); // 假设读取了 00cccccc 到 c4 (c 表示 1 或 0)
if (c4 == 255)
break; // 如果遇到编码结束符 == 255 就退出解码过程
// 用(00000011)截取八位的c3中最后两位,左移六位,成为解码的头部
// c4中最后六位,成为解码的尾部
*bp++ = ((c3 & 0x03) << 6) | c4; // (cc000000) | (00cccccc)
p += 4; // p 移动到 下一组(四个) 编码的开头
}
}
----------------------
参考2:
char *b64index = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
bool Base64Decode(char *code, char *txt)
{
int len = strlen(code);
if(len % 4) return false;
char *buf = new char[len];
int i,j;
bool p = false;
for(i = 0; i < len; i++)
{
p = false;
for(j = 0; j < 64; j++)
{
if(code[i] == b64index[j] || code[i] == '=')
{
buf[i] = j;
p = true;
break;
}
}
if(!p)
return false; //出现非法字符
}
if(code[len - 1] == '=') buf[len - 1] = 0;
if(code[len - 2] == '=') buf[len - 2] = 0;
for(i = 0; i < len / 4; i++)
{
txt[i * 3] = buf[i * 4] << 2 & 0xFC | ( buf[i * 4 + 1] >> 4 & 0x03);
txt[i * 3 + 1] = buf[i * 4 + 1] << 4 & 0xF0 | ( buf[i * 4 + 2] >> 2 & 0x0F);
txt[i * 3 + 2] = buf[i * 4 + 2] << 6 & 0xC0 | buf[i * 4 + 3];
}
txt[len * 6 / 8] = '\0';
delete buf;
return true;
}
--------------------------------
参考3:
base64编码
/*
*
*Base64?
*
*
*
*/
#include "Base64.h"
static
const
char
*g_pCodes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
;
static
const
unsigned
char
g_pMap[256] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255
};
CBase64::CBase64()
{
}
CBase64::~CBase64()
{
}
bool
CBase64::Encode(
const
unsigned
char
*pIn, unsigned
long
uInLen, unsigned
char
*pOut, unsigned
long
*uOutLen)
{
unsigned
long
i, len2, leven;
unsigned
char
*p;
if
(pOut == NULL || *uOutLen == 0)
return
false
;
//ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
len2 = ((uInLen + 2) / 3) << 2;
if
((*uOutLen) < (len2 + 1))
return
false
;
p = pOut;
leven = 3 * (uInLen / 3);
for
(i = 0; i < leven; i += 3)
{
*p++ = g_pCodes[pIn[0] >> 2];
*p++ = g_pCodes[((pIn[0] & 3) << 4) + (pIn[1] >> 4)];
*p++ = g_pCodes[((pIn[1] & 0xf) << 2) + (pIn[2] >> 6)];
*p++ = g_pCodes[pIn[2] & 0x3f];
pIn += 3;
}
if
(i < uInLen)
{
unsigned
char
a = pIn[0];
unsigned
char
b = ((i + 1) < uInLen) ? pIn[1] : 0;
unsigned
char
c = 0;
*p++ = g_pCodes[a >> 2];
*p++ = g_pCodes[((a & 3) << 4) + (b >> 4)];
*p++ = ((i + 1) < uInLen) ? g_pCodes[((b & 0xf) << 2) + (c >> 6)] :
'='
;
*p++ =
'='
;
}
*p = 0;
// Append NULL byte
*uOutLen = p - pOut;
return
true
;
}
bool CBase64::Encode(const unsigned char *pIn, unsigned long uInLen, string& strOut)
{
unsigned long i, len2, leven;
strOut = "";
//ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
len2 = ((uInLen + 2) / 3) << 2;//编码后的字符长度,等价于((uInLen+2)/3)*4
//if((*uOutLen) < (len2 + 1)) return false;
//p = pOut;
leven = 3 * (uInLen / 3);//前leven个字符是3的倍数,无需要补充“=”,只有最后的哪1-2个字符需要添加=号填充,uInLen%3求余即可得剩余的需要特殊处理的字符数
//如pIn为“abcdefgh”,此时leven为6,剩余的gh需要进行特殊处理,前面6个字符可以在下面的for循环中进行编码
//每3个字符组成一组,经过一次for循环后变成4个字符--3个8位字符拆成4个6位然后分别在4个6位前面添加两个0
for(i = 0; i < leven; i += 3)
{
strOut += g_pCodes[pIn[0] >> 2];//第一个字符右移2位得高6位形成的索引组成新组的第一个字符
strOut += g_pCodes[((pIn[0] & 3) << 4) + (pIn[1] >> 4)];//大意:当前组的第一个字符的二进制的低2位前面补两个0和第二个字符的高4位拼接成8位得到编码后的第二个字符
strOut += g_pCodes[((pIn[1] & 0xf) << 2) + (pIn[2] >> 6)];//当前组的第二个字符的低4位(前面还加了两个0,加号前面的意义其实是0000+低四位字符,然后再左移两位,移去了高两位的0,相当于给第四位前面补了两个0),和第三个字符的高2位拼接成新的组合的第三个字符
strOut += g_pCodes[pIn[2] & 0x3f];//取得当前组的第三个字符的低6位得base64表的索引位置(前面的两个0对索引值无意义)
pIn += 3;
}
if (i < uInLen)
{
unsigned char a = pIn[0];
unsigned char b = ((i + 1) < uInLen) ? pIn[1] : 0;
unsigned char c = 0;
strOut += g_pCodes[a >> 2];
strOut += g_pCodes[((a & 3) << 4) + (b >> 4)];
strOut += ((i + 1) < uInLen) ? g_pCodes[((b & 0xf) << 2) + (c >> 6)] : '=';
strOut += '=';
}
//*p = 0; // Append NULL byte
//*uOutLen = p - pOut;
return true;
}
bool
CBase64::Decode(
const
string& strIn, unsigned
char
*pOut, unsigned
long
*uOutLen)
{
unsigned
long
t, x, y, z;
unsigned
char
c;
unsigned
long
g = 3;
//ASSERT((pIn != NULL) && (uInLen != 0) && (pOut != NULL) && (uOutLen != NULL));
for
(x = y = z = t = 0; x < strIn.length(); x++)
{
c = g_pMap[strIn[x]];
if
(c == 255)
continue
;
if
(c == 254) { c = 0; g--; }
t = (t << 6) | c;
if
(++y == 4)
{
if
((z + g) > *uOutLen) {
return
false
; }
// Buffer overflow
pOut[z++] = (unsigned
char
)((t>>16)&255);
if
(g > 1) pOut[z++] = (unsigned
char
)((t>>8)&255);
if
(g > 2) pOut[z++] = (unsigned
char
)(t&255);
y = t = 0;
}
}
*uOutLen = z;
return
true
;
}
引用自:http://my.youkuaiyun.com/cclongying1989/code/detail/13009