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的解码过程,是编码的逆过程,放在下一节讲解