base64
百度百科:
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
Base-64编码将一个8位子节序列拆散为6位的片段,并为每个6位的片短分配一个字符,这个字符是Base-64字母表中的64个字符之一
简单的Base64 编码实现,现输入值 " Ow! "进行Base64编码:
1.将字符串拆分成3个8位的字节(0x4f、0x77、0x21)
2.这3个字节构成24位的二进制 0100 1111 0111 0111 0010 0001
3.将二进制以每6位的序列划分 010011 110111 011100 100001
4.在Base64编码表中索引对应的字符 T(19) 3(55) c(28) h(33)
---------------------------------- 分割线 ---------------------------------------
O(0x4f) w(0x77) !(0x21)
0100 1111 0111 0111 0010 0001
010011 110111 011100 100001
T(19) 3(55) c(28) h(33)
------------------------------------------------------------------------------------
编码输出为:T3ch
Base64填充
base64编码收到一个8位字节序列,将这个二进制序列流划分成6位的块。二进制序列有时不能正好平均地分为6位的块,在这种情况下,就在序列末尾填充零位,使二进制序列的长度成为24的倍数(6和8的最小公倍数)。
对已填充的二进制进行编码时,任何完全填充(不包括原始数组中的位)的6位组都有特殊的第65个符号"="表示。如果6位组是部分填充的,就将填充位设置为0.
现输入值” a : a a "进行Base64编码:
1.将字符串拆分成4个8位的字节(0x61、0x3A、0x61、0x61)
2.这4个字节构成32位的而进制 01100001 00111010 01100001 01100001
3.将二进制以每6位的顺序划分(因为32不是6和8的公倍数,所以要添加16个字节以达到6和8的公倍数48) 011000 010011 101001 100001 011000 01xxxx xxxxxx xxxxxx
4.在Base64编码表中索引对应的字符 Y(24) T(19) P(41) h(33) Y(24) Q(16) = =
---------------------------------- 分割线 ---------------------------------------
a : a a
0x61 0x3A 0x61 0x61
01100001 00111010 01100001 01100001
011000 010011 101001 100001 011000 01xxxx xxxxxx xxxxxx
Y(24) T(19) P(41) h(33) Y(24) Q(16) = =
------------------------------------------------------------------------------------
编码结果:YTphYq==
c++实现代码(借鉴网上的代码,实现的不太标准有部分问题):
#include <iostream> #include <cstring> using namespace std; using std::cout; using std::endl; using std::string; static const char b64_table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; bool Encode(const unsigned char* pIn, unsigned long uInLen,std::string& strOut){ unsigned long i,len2,leven; strOut = ""; len2 = ((uInLen + 2)/3 )<<2; leven = 3 * (uInLen/3); for (i=0;i <leven ; ++i) { strOut += b64_table[pIn[0] >>2]; strOut += b64_table[((pIn[0]&3)<<4)+(pIn[1]>>4)]; strOut += b64_table[((pIn[1]&0xf)<<2)+(pIn[2]>>6)]; strOut += b64_table[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; strOut += b64_table[a >> 2]; strOut += b64_table[((a & 3)<<4) + (b>>4)]; strOut += ((i+1) <uInLen )?b64_table[((b & 0xf)<<2)+(c>>6)]:'='; strOut += '='; } return true; } int main(){ //base64 编码 unsigned char pIn[100]; memcpy(pIn,"a:aa",5); string strout; cout<<pIn<<endl; if (Encode(pIn,4,strout)) //printf("编码成功!"); cout<<strout<<endl; else cout<<"编码失败"<<endl; return 0; }