Base64编码.docx
- 文档编号:9892316
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:46
- 大小:30.74KB
Base64编码.docx
《Base64编码.docx》由会员分享,可在线阅读,更多相关《Base64编码.docx(46页珍藏版)》请在冰豆网上搜索。
Base64编码
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64编码可用于在HTTP环境下传递较长的标识信息。
例如,在JavaPersistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTPGETURL中的参数。
在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。
此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
目录
标准的Base64
简介
规则
转换表
举例
在URL中的应用
在下载软件中加密下载地址的原理
PHP中的解密下载地址的实现
VB版的Base64编码函数定义
JS版的Base64编码函数定义
JS实现BASE64加密、解密算法
C#实现BASE64加密、解密算法
自己完成算法实现
直接使用.NET中的的库类函数
Base64-MIME
标准的Base64
简介
规则
转换表
举例
在URL中的应用
在下载软件中加密下载地址的原理
PHP中的解密下载地址的实现
VB版的Base64编码函数定义
JS版的Base64编码函数定义
JS实现BASE64加密、解密算法
C#实现BASE64加密、解密算法
自己完成算法实现
直接使用.NET中的的库类函数
Base64-MIME
展开
编辑本段标准的Base64
简介
标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSISQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“*”和“-”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!
”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:
”(用于XML中的Name)。
Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8=4*6=24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
规则
关于这个编码的规则:
①.把3个字符变成4个字符..
②每76个字符加一个换行符..
③.最后的结束符也要处理..
这样说会不会太抽象了?
不怕,我们来看一个例子:
转换前aaaaaabbccccddddeeffffff
转换后00aaaaaa00bbcccc00ddddee00ffffff
应该很清楚了吧?
上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。
转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:
(摘自RFC2045)
转换表
Table1:
TheBase64Alphabet
ValueEncodingValueEncodingValueEncodingValueEncoding
0A17R34i51z
1B18S35j520
2C19T36k531
3D20U37l542
4E21V38m553
5F22W39n564
6G23X40o575
7H24Y41p586
8I25Z42q597
9J26a43r608
10K27b44s619
11L28c45t62+
12M29d46u63/
13N30e47v
14O31f48w(pad)=
15P32g49x
16Q33h50y
索引
对应字符
索引
对应字符
索引
对应字符
索引
对应字符
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
举例
让我们再来看一个实际的例子,加深印象!
转换前101011011011101001110110
转换后00101011000110110010100100110110
十进制43274154
对应码表中的值rbp2
所以上面的24位编码,编码后的Base64值为rbp2
解码同理,把rbq2的二进制位连接上再重组得到三个8位值,得出原码。
(解码只是编码的逆过程,在此我就不多说了,另外有关MIME的RFC还是有很多的,如果需要详细情况请自行查找。
)
用更接近于编程的思维来说,编码的过程是这样的:
第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一个目标字符。
然后将第一个字符左移4位加上第二个字符右移4位,即获得第二个目标字符。
再将第二个字符左移2位加上第三个字符右移6位,获得第三个目标字符。
最后取第三个字符的右6位即获得第四个目标字符。
在以上的每一个步骤之后,再把结果与0x3F进行AND位操作,就可以得到编码后的字符了。
可是等等……聪明的你可能会问到,原文的字节数量应该是3的倍数啊,如果这个条件不能满足的话,那该怎么办呢?
我们的解决办法是这样的:
原文的字节不够的地方可以用全0来补足,转换时Base64编码用=号来代替。
这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。
因为:
余数=原文字节数MOD3
所以余数任何情况下都只可能是0,1,2这三个数中的一个。
如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况啦)。
如果是1的话,为了让Base64编码是3的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。
编辑本段在URL中的应用
Base64编码可用于在HTTP环境下传递较长的标识信息。
例如,在JavaPersistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTPGETURL中的参数。
在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。
此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
然而,标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSISQL中已将“%”号用作通配符。
为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“*”和“-”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。
另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!
”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。
此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:
”(用于XML中的Name)。
编辑本段在下载软件中加密下载地址的原理
先以“迅雷下载”为例:
很多下载类网站都提供“迅雷下载”的链接,其地址通常是加密的迅雷专用下载地址。
如thunder:
//QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
其实迅雷的“专用地址”也是用Base64加密的,其加密过程如下:
一、在地址的前后分别添加AA和ZZ
如
AA
二、对新的字符串进行Base64编码
如AA
QUF3d3cuYmFpZHUuY29tL2ltZy9zc2xtMV9sb2dvLmdpZlpa
三、在上面得到的字符串前加上“thunder:
//”就成了
thunder:
//QUF3d3cuYmFpZHUuY29tL2ltZy9zc2xtMV9sb2dvLmdpZlpa
另:
Flashget的与迅雷类似,只不过在第一步时加的“料”不同罢了,Flashget在地址前后加的“料”是[FLASHGET]
而QQ旋风的干脆不加料,直接就对地址进行Base64编码了
编辑本段PHP中的解密下载地址的实现
[下列代码仅在GBK中实现,UTF8代码请把if($button=="迅雷地址->普通地址")echosubstr(base64_decode(str_ireplace("thunder:
//","",$txt1)),2,-2);这句改为if($button=="迅雷地址->普通地址")echosubstr(mb_convert_encoding(base64_decode(str_ireplace("thunder:
//","",$txt1))),2,-2);并把charset=gb2312改为charset=utf-8]
php
$txt1=trim($_POST['text1']);
$txt2=trim($_POST['text2']);
$txt3=trim($_POST['text3']);
$button=$_POST['button'];
?
>
DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN">
迅雷转换
转换地址:
phpecho$txt1;? >"type="text"style="width: 516px;"/>
转换后的:
php if($button=="普通地址->迅雷地址")echo"thunder: //".base64_encode("AA".$txt1."ZZ"); if($button=="迅雷地址->普通地址")echosubstr(base64_decode(str_ireplace("thunder: //","",$txt1)),2,-2); ? >"style="width: 516px;"/>
FlashGet转换
FlashGet地址:
phpecho$txt2;? >"type="text"style="width: 516px;"/>
转换后地址:
php if($button=="普通地址->FlashGet地址")echo"flashget: //".base64_encode($txt2); if($button=="FlashGet地址->普通地址")echostr_ireplace("[FLASHGET]","",base64_decode(str_ireplace("flashget: //","",$txt2))); ? >"style="width: 516px;"/>
QQ旋风转换
QQ旋风地址:
phpecho$txt3;? >"type="text"style="width: 516px;"/>
转换后地址:
php if($button=="普通地址->QQ旋风")echo"qqdl: //".base64_encode($txt3); if($button=="QQ旋风->普通地址")echobase64_decode(str_ireplace("qqdl: //","",$txt3)); ? >"style="width: 516px;"/>
编辑本段VB版的Base64编码函数定义
注:
其中DigestStrToHexStr为可在程序外部调用加密函数
OptionExplicit
'Base64Encoding/DecodingAlgorithm
'By:
DavidMidkiff(mznull@)
'
'ThisalgorithmsencodesanddecodesdataintoBase64
'format.Thisformatisextremelymoreefficientthan
'Hexadecimalencoding.
Privatem_bytIndex(0To63)AsByte
Privatem_bytReverseIndex(0To255)AsByte
PrivateConstk_bytEqualSignAsByte=61
PrivateConstk_bytMask1AsByte=3
PrivateConstk_bytMask2AsByte=15
PrivateConstk_bytMask3AsByte=63
PrivateConstk_bytMask4AsByte=192
PrivateConstk_bytMask5AsByte=240
PrivateConstk_bytMask6AsByte=252
PrivateConstk_bytShift2AsByte=4
PrivateConstk_bytShift4AsByte=16
PrivateConstk_bytShift6AsByte=64
PrivateConstk_lMaxBytesPerLineAsLong=152
PrivateDeclareSubCopyMemoryLib"kernel32"Alias"RtlMoveMemory"(ByValDestinationAsLong,ByValSourceAsLong,ByValLengthAsLong)
PublicFunctionDecode64(sInputAsString)AsString
IfsInput=""ThenExitFunction
Decode64=StrConv(DecodeArray64(sInput),vbUnicode)
EndFunction
PrivateFunctionDecodeArray64(sInputAsString)AsByte()
DimbytInput()AsByte
DimbytWorkspace()AsByte
DimbytResult()AsByte
DimlInputCounterAsLong
DimlWorkspaceCounterAsLong
bytInput=Replace(Replace(sInput,vbCrLf,""),"=","")
ReDimbytWorkspace(LBound(bytInput)To(UBound(bytInput)*2))AsByte
lWorkspaceCounter=LBound(bytWorkspace)
ForlInputCounter=LBound(bytInput)ToUBound(bytInput)
bytInput(lInputCounter)=m_bytReverseIndex(bytInput(lInputCounter))
NextlInputCounter
ForlInputCounter=LBound(bytInput)To(UBound(bytInput)-((UBound(bytInput)Mod8)+8))Step8
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
bytWorkspace(lWorkspaceCounter+1)=((bytInput(lInputCounter+2)Andk_bytMask2)*k_bytShift4)+(bytInput(lInputCounter+4)\k_bytShift2)
bytWorkspace(lWorkspaceCounter+2)=((bytInput(lInputCounter+4)Andk_bytMask1)*k_bytShift6)+bytInput(lInputCounter+6)
lWorkspaceCounter=lWorkspaceCounter+3
NextlInputCounter
SelectCase(UBound(bytInput)Mod8):
Case3:
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
Case5:
bytWorkspace(lWorkspaceCounter)=(bytInput(lInputCounter)*k_bytShift2)+(bytInput(lInputCounter+2)\k_bytShift4)
bytWorkspace(lWorkspaceCounter+1)=((bytInput(lInputCounter+2)Andk_bytMask2)*k_bytShift4)+(bytInput(lInputCounter+4)\k_bytShift2)
lWorkspaceCounter=lWorkspaceCounter+1
Case7:
bytW
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Base64 编码