Base64 使用US-ASCII子集的64个字符,即大小写的26个英文字母、0~9以及+、/。
编码总是基于3个字符,每个字符用8位二进制表示,因此一共24位,再分为4组,每组6位,表示一个Base64的值。如下:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/。
Base64值为0就是A,为27的就是b,每3个字符产生4位的Base64字符,如果被加密的字符串每3个一组,还剩1或2个字符,使用特殊字符"="补齐Base64的4字。如编码只有2个字符“me”,m的ascii是109,e的是101,用二进制表示分别是01101101、01100101,连接起来就是0110110101100101,再按6位分为一组:011011、010110、010100(不足6位补0),分别ascii分别是27、22、20,即Base64值为bWU,Base64不足4字,用=补齐,因此bWU=就me的Base64值。
Base64的主要功能是可以把二进制文件和文本文件进行相互转换,用于使仅能以文本方式进行传输和存储的系统能够处理二进制文件,比如在某些只能使用文本方式的Email系统和不能够上传附件的论坛和BBS等上面使用二进制文件。
Base64加密内容是肯定的,但是加密的目的不是让用户发送非常安全的Email,这种加密方式主要就是“防君子不防小人”,即达到一眼望去完全看不出内容即可。
void
ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
{
static u_char basis64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
ngx_encode_base64_internal(dst, src, basis64, 1);
}
static void
ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis,
ngx_uint_t padding)
{
u_char *d, *s;
size_t len;
len = src->len;
s = src->data;
d = dst->data;
//3个byte-------->4个byte
while (len > 2) {
*d++ = basis[(s[0] >> 2) & 0x3f]; // 0x3f=00111111,第1个字符的前6bit
*d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)]; //第1个字符的后2bit,和第2个字符的前4bit
*d++ = basis[((s[1] & 0x0f) << 2) | (s[2] >> 6)]; //第2个字符的后4bit和第3个字符的前2bit
*d++ = basis[s[2] & 0x3f]; //第3个字符的后6bit
s += 3;
len -= 3;
}
//’d’=01100100,比如helloworld=aGVs bG93 b3Js ZA==
if (len) {
*d++ = basis[(s[0] >> 2) & 0x3f]; //第1个字符的前6bit=11001=25=’Z’
if (len == 1) { //len=1,共8bit
*d++ = basis[(s[0] & 3) << 4]; //第1个字符的后2bit=0=’A’
if (padding) {
*d++ = '='; //=
}
} else { //len=2,共8*2=16bit
*d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
*d++ = basis[(s[1] & 0x0f) << 2];
}
if (padding) {
*d++ = '='; //=
}
}
dst->len = d - dst->data;
}
ngx_int_t
ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
{
static u_char basis64[] = {
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
77, 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, 77, 77, 77, 77, 77,
77, 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, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
};
return ngx_decode_base64_internal(dst, src, basis64);
}
static ngx_int_t
ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis)
{
size_t len;
u_char *d, *s;
for (len = 0; len < src->len; len++) {
if (src->data[len] == '=') {
break;
}
if (basis[src->data[len]] == 77) {
return NGX_ERROR;
}
}
if (len % 4 == 1) {
return NGX_ERROR;
}
s = src->data;
d = dst->data;
while (len > 3) {
*d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
*d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
*d++ = (u_char) (basis[s[2]] << 6 | basis[s[3]]);
s += 4;
len -= 4;
}
if (len > 1) {
*d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
}
if (len > 2) {
*d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
}
dst->len = d - dst->data;
return NGX_OK;
}
http://blog.163.com/gaoguangtao_love/blog/static/38483715201242984016259/