Contents

初试base64编码

今天来记录一下Base64编码的事吧,其实这玩意也谈不上是编码,只是一个字符串转换的事!不过我觉得有必要装一下这个逼,一天不装浑身难受,哈哈。。。

这里贴个Base64的介绍吧,来自百度百科:

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

Base64的详细编码方式

所谓Base64,就是说选出64个字符—-小写字母a-z、大写字母A-Z、数字0-9、符号”+”、”/“(再加上作为垫字的”=”,实际上是65个字符)—-作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

具体来说,转换方式可以分为四步。

第一步,将每三个字节作为一组,一共是24个二进制位。

第二步,将这24个二进制位分为四组,每个组有6个二进制位。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。

第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

/images/base64_1.png 编码表

到这我们可能会发现,如果原始的字符串的字节数不是三的倍数,怎么办???

好,这个问题有意思。在Base64的规则里是这么规定的:

当剩下的字符数量不足3个字节时,则应使用0进行填充,相应的,输出字符则使用’=’占位

举个栗子

转前: s 1 3

先转成ascii:对应 115 49 51

2进制: 01110011 00110001 00110011

6个一组(4组) 011100110011000100110011

然后才有后面的 011100 110011 000100 110011

然后计算机是8位8位的存数 6个不够,自动就补两个高位0了

所有有了 高位补0

科学计算器输入 00011100 00110011 00000100 00110011

得到 28 51 4 51

查下编码表 c z E z

所以Base64就是将3个字节拓展成四个字节来达到所谓的编码

贴个c语言的源码 注:只包含编码模块

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdio.h>
#include<string.h>
/*
此程序用来进行base64编码
*/
void encrypt64(char *three_bits,char *four_bits)
{   //编码函数
    const unsigned char base64_enc_map[64] ={ //进行base64转换的码表
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
    'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', '+', '/'};
    union{ unsigned char a[3];unsigned int b;} a;
    int i;
    for(i=0;i<3;i++)    //把读取的3个字节赋给联合体a
    a.a[2-i]=three_bits[i];
    for(i=0;i<4;i++)
    {
        four_bits[3-i]=base64_enc_map[a.a[0]&63];
        a.b=a.b>>6;
    }
    four_bits[4]='\0';
}
void translate(char *source,char *encrypted)
{           //通过此函数来将原字符串进行分割,并进行转换
     int len=strlen(source),i;
     char four_bits[5];
     for(i=0;i<len-2;i+=3)
     {
            encrypt64(&source[i],four_bits);
            strcat(encrypted,four_bits);
     }
     if(len%3==1)
        {
            encrypt64(&source[len-1],four_bits);
            four_bits[2]='\0';
            strcat(encrypted,four_bits);
            strcat(encrypted,"==");
        }
    if(len%3==2)
        {
            encrypt64(&source[len-2],four_bits);
            four_bits[3]='\0';
            strcat(encrypted,four_bits);
            strcat(encrypted,"=");
        }
}
void main()
{
    char a[]="hello world !",b[30]=""; //a字串是需要加密的字串,b为储存加密过后的字串
    translate(a,b);
    printf("the original string is :\n %s\n",a);
    printf("the string is encrypted : \n%s\n",b);
}

程序短小精悍有木有,运行起来很快有木有,只依赖两个标准库,可以随便移植随便哪个平台都可以跑有木有,当然这是c的长处嘛

来贴个运行截图: /images/base64_2.png 我是图

这个框框是这么的熟悉有木有,哈哈。黑色的框框

好了,Base64解码的坑有时间再来填吧,拜了个拜嘞。。。