base64编码详解

来源:互联网 发布:单片机系统可靠性 编辑:程序博客网 时间:2024/05/18 03:15
std::string Basic_64::GetBase64Str(std::string& StrSource){
std::string EnCodeStr="";//存放最终的返回结果const char *chKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64的ascii表  int lenString = StrSource.length();int nLoop=lenString/3;//需要循环的次数(每3个字节作为一组,循环使用)int n=0,k=0;//n表示二进制的位数,k表示循环的次数  int b[3]={0};//存放ascii值   if (nLoop <= 0){//计算剩余的字节数,采用“=”补位int j = lenString % 3;  switch(j)  {  case 0:  EnCodeStr[n]='\0';  break;  case 1:  b[0]=StrSource[0];EnCodeStr+=chKey[(b[0] & 0xfc)>>2];EnCodeStr+=chKey[(b[0] & 0x03)<<4 | ((0 & 0xf0)>>4)];  EnCodeStr+="==";break;  case 2:  b[0]=StrSource[0];  b[1]=StrSource[1]; EnCodeStr+=chKey[(b[0] & 0xfc)>>2]; EnCodeStr+=chKey[(b[0] & 0x03)<<4 | (b[1] & 0xf0)>>4];  EnCodeStr+=chKey[(b[1] & 0x0f)<<4 | ((0 & 0xc0)>>6)];  EnCodeStr+="=";   break;  } return EnCodeStr.c_str();}for( k = 0 ; k < lenString; k+=3 ){//根据3*8=4*6可以得到每3个字节一个轮回,这个循环只有大于等于3个字节,才可以进入该循环  //用int类型存储char类型的ASCII码值if (k >= lenString){break;}b[0]=StrSource[k];EnCodeStr+=chKey[(b[0] & 0xfc/*11111100*/)>>2];//获得第一个字节的前6位(使用11111100和b[0]相与,然后右移2位得到结果)if ( (k+1)<lenString ){b[1]=StrSource[k+1];EnCodeStr+=chKey[(b[0] & 0x03/*00000011*/)<<4 | (b[1] & 0xf0/*11110000*/)>>4];if ( (k+2)<lenString ){b[2]=StrSource[k+2];EnCodeStr+=chKey[(b[1] & 0x0f/*00001111*/)<<2 | (b[2] & 0xc0/*11000000*/)>>6];EnCodeStr+=chKey[(b[2] & 0x3f/*00111111*/)];}else//(k+2)>lenString{EnCodeStr+=chKey[(b[1] & 0x0f/*00001111*/)<<2 | ((0 & 0xc0/*11000000*/)>>6)];  EnCodeStr+="=";  }}else//(k+1)>lenString{EnCodeStr+=chKey[(b[0] & 0x03/*00000011*/)<<4 | ((0 & 0xf0/*11110000*/)>>4)];  EnCodeStr+="==";  }}  return EnCodeStr.c_str();  }


通过上面的代码就可以将可见字符转化为base64位的编码形式。
1、引入64位编码的原因:为了在http传递的过程中,为了隐藏较长的标识符,引入了base64位编码。通过64位编码之后,数据无法用肉眼识别,因此有很好的保密性。
如:迅雷下载,在很多的网站上都提供迅雷下载的链接地址,这个地址是通过在地址前后分别加入AA,ZZ之后,使用base64位编码算法加密后的地址,因此这个地址是无法识别的。
2、编码的原理:其实很简单,将8位2进制数据转化为6位2进制数据的标示形式
具体的做法是:1)、将一个字节8位2进制,从高位到低位,6位2进制分为1组,然后将这些6位2进制字节组,向右移动2位(即最高位补00),这样就构成了一个新的字节,通过比较base64的ascii表,得到相应的字符;2)如果得到6位2进制数据后,剩余的2进制位无法构成一个6位数,这时就需要分两种情况处理。当剩余2个2进制位时,这时就需要补4个二进制位,base64规定,在这2个二进制后面,添加两个"=",作为补位(其实内容中是补两个00,显示的时候使用=),然后最高位补00,这样就构成了一个8位二进制数;当剩余4个2进制位时,这时就需要补2个二进制位,base64规定,在这4个二进制后面,添加一个"=",作为补位,然后最高位补00,构成一个新字节。
3)构成新的字节后,从base64的ascii表,得到相应的字符,得到最终编码后的字符串。
例如:A(二进制位:01000001)
首先得到第一个6位二进制:010000,然后高位补00,得到的新8位二进制数为:00010000
然后得到第二个6位二进制:因为剩余01,所以在01后面不两个00,得到010000,然后高位补00,得到的新8位二进制数为:00010000
最终得到的两个字节为:00010000  00010000;通过查base64的ascii表可得知为QQ,所以最终的结果为QQ==
如:ABC(二进制编码为:01000001  01000010  01000011)
首先得到第一个6位二进制:010000,然后高位补00,得到的新8位二进制数为:00010000
再次得到第二个6位二进制:010100,然后高位补00,得到的新8位二进制数为:00010100
再次得到第三个6位二进制:001001,然后高位补00,得到的新8位二进制数为:00001001
最后得到第四个6位二进制:000011,然后高位补00,得到的新8位二进制数为:00000011
最终得到的四个字节为:00010000  00010100  00001001  00000011;通过查base64的ascii表可得最终的结果为QUJD

base64的ascii表为:
索引
对应字符
索引
对应字符
索引
对应字符
索引
对应字符
0
A
17
R
34
i
51
z
1
B
18
S
35
j
52
0
2
C
19
T
36
k
53
1
3
D
20
U
37
l
54
2
4
E
21
V
38
m
55
3
5
F
22
W
39
n
56
4
6
G
23
X
40
o
57
5
7
H
24
Y
41
p
58
6
8
I
25
Z
42
q
59
7
9
J
26
a
43
r
60
8
10
K
27
b
44
s
61
9
11
L
28
c
45
t
62
+
12
M
29
d
46
u
63
/
13
N
30
e
47
v
  
14
O
31
f
48
w
  
15
P
32
g
49
x
  
16
Q
33
h
50
y



对于base64的解码过程,是编码的逆过程,放在下一节讲解

1 0
原创粉丝点击