base64编码详解

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值