您的位置:首页 > 其它

perl处理base64编码解码问题

2014-08-21 16:02 423 查看


Base-64编码

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。

Base64要求把每三个8Bit的字节转换为
4000
四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

这样说会不会太抽象了?不怕,我们来看一个例子:
转换前aaaaaabbccccddddeeffffff 
转换后00aaaaaa00bbcccc00ddddee00ffffff
应该很清楚了吧?上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。

转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:(摘自RFC2045)

                            Table 1: The Base64 Alphabet

      Value Encoding  Value Encoding  Value Encoding  Value Encoding

           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         (pad) =

          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 位操作,就可以得到编码后的字符了。

So easy! That’s all!!!

可是等等……聪明的你可能会问到,原文的字节数量应该是3的倍数啊,如果这个条件不能满足的话,那该怎么办呢?

我们的解决办法是这样的:原文的字节不够的地方可以用全0来补足,转换时Base64编码用=号来代替。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为:

余数 = 原文字节数 MOD 3

所以余数任何情况下都只可能是0,1,2这三个数中的一个。如果余数是0的话,就表示原文字节数正好是3的倍数(最理想的情况啦)。如果是1的话,为了让Base64编码是4的倍数,就要补2个等号;同理,如果是2的话,就要补1个等号。

讲到这里,大伙儿应该全明白了吧?如果还有不清楚的话就返回去再仔细看看,其实不难理解的。

下面我给出一个演示Base64编码/解码的程序,希望能对您有用。同时也希望您帮我完善它,利用它做出更多的用途,到时别忘了通知我一声啊!(我现在太忙了)

P.S. 为什么取名叫Base64:

        base64此编码方式可以让中文字或者图片也能在网路上顺利传输。在 BASE64 编码后的字串只包含英文字母大小写、阿拉伯数字、加号与反斜线,共 64 个基本字元,不包含其它特殊的字元,因而才取名 BASE64。编码后的字串比原来的字串长度再加 1/3 左右。

Base-64编码

Base-64编码可以将任意一组字节转换成较长的(扩大了33%)常见文本字符序列,从而可以合法地作为HTTP首部字段值。即,Base-64编码将用户输入或二进制数据打包成一种安全的格式,将其作为HTTP首部字段的值发送出去,而无须担心其中包含会破坏HTTP分析程序的冒号、换行符或二进制值。

8位到6位

Base-64编码将一个8位字节拆分为6位的片段,并为每个6位的片段分配一个字符(Base-64字母表中的64个字符之一,0~63),这64个字符中包含26个大写字母、26个小写字母、10个数字、‘+’和‘/’2个字符,共64个字符,另外还使用了特殊字符‘=’。

Base-64填充

Base-64编码收到一个8位字节序列,将这个二进制序列流划分成6位的块。但二进制序列有时不能正好平均地分成6位的块,在这种情况下,就在序列末尾填充零位,使二进制序列的长度成为24的倍数(即,6和8的最小公倍数)。

对已填充的二进制串进行编码时,任何完全填充(不包含原始数据中的位)的6位组都由特殊的第65个符号‘=’表示;如果6位组是部分填充的,就将填充的位设置为0。

编码「Man」
文本Man
ASCII编码7797110
二进制位010011010110000101101110
索引1922546
Base64编码TWFu
在此例中,Base64算法将三个字符编码为4个字符

Base64索引表:
ValueChar ValueChar ValueChar ValueChar
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

Perl实现

MIME::Base64是Perl中的Base-64编/解码模块。

#!/usr/bin/perl  

  

use MIME::Base64;  

  

printf("orignal string is 'Man'\n");  

$encoded = encode_base64('Man');  

printf("after base64 encoded is: %s", $encoded);  

$decoded = decode_base64($encoded);  

printf("after base64 decoded is: %s\n\n", $decoded);  

  

  

printf("\nencode_base64\n");  

  

# YTph  

$encoded1 = encode_base64('a:a');  

print $encoded1;  

  

# YTphYQ==  

$encoded2 = encode_base64('a:aa');  

print $encoded2;  

  

# YTphYWE=  

$encoded3 = encode_base64('a:aaa');  

print $encoded3;  

  

# YTphYWFh  

$encoded4 = encode_base64('a:aaaa');  

print $encoded4;  

  

printf("\ndecode_base64\n");  

  

$decoded1 = decode_base64($encoded1);  

print $decoded1 ."\n";  

  

$decoded2 = decode_base64($encoded2);  

print $decoded2 ."\n";  

  

$decoded3 = decode_base64($encoded3);  

print $decoded3 ."\n";  

  

$decoded4 = decode_base64($encoded4);  

print $decoded4 ."\n";  

  

system(pause);  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: