什么是base64
那么,Base64又是什么呢?和我们听说过的Hex编码,ASCII编码,UTF-8编码什么的,有什么关系吗?我尽量用简单的语言来讲讲故事。
计算机开始之初,二进制与Hex
计算机这个东西,最初是美国人发明的。作为一个可以计算、存储、通信的复杂玩意,最最基本的功能,应该是能读懂人类让它干的事情。所以呢,我们得构造一个计算机能用的语言,这个语言计算机能看懂,人也能看懂,这样才能交流嘛。
计算机所用的语言是什么呢?这个语言非常简单,只有0和1两种表示。0代表否,1代表是。通过0和1的各种组合,以及0和1之间的各种运算(位运算),计算机就能进行理解、分析这个世界,并帮助人类完成工作了。
但是0和1太简单了,简单到任何一个简单的数字都可能用一长串0和1来表示。举了例子,如果让计算机记住1000这个数,计算机就要记住11,1110,1000这么长一串数字。计算机倒是好记,但是人类记不住啊… 有没有一种方法,能够让计算机表示的数据短一点,好记一点呢?
Hex就是最简单的方法了。人类习惯于使用十进制,毕竟人类有是个手指,十个一进位,挺好的!计算机本质上是二进制,就0和1两种数字的表示方法,所有其他可以直接转换的表示方法中,进制只能有2这个数,不能有其他的数字。比如4,8,16就没问题。其他的数字,不管怎么折腾,转换后也得是2^n形式。
想让人类和计算机都能接受表示形式,8进制和16进制都是可以接受的。8进制的话,只使用0-7折8个数字就好了。16进制,光用数字是不够了,还得用用其他的字符。然而,计算机毕竟是美国人发明的,他们觉得,干脆,就16进制:用0-9表示前10个数,后面的用A、B、C、D、E、F表示,不区分大小写。这就是最简单的Hex编码了。
Hex的编码原理是:把一长串二进制数每4个分一组,如果位数不够就在高位补0。4位数字一共只有16种情况,分别用0-9,A-F表示这16种情况。编码表类似这样:
要让可读性更强:ASCII码
Hex编码虽然好,但有个问题:从计算机上打开个文件,满眼的十六进制数,很头大啊… 十六进制还是不太好表示文本。能不能创建一种方法,能表示键盘打出来的全部英文字符、符号呢?键盘打不出来的字符,比如什么回车啦,占位啦,用特殊的符号表示。这样一来,打开一个文件,满眼英文,岂不是很爽快…
美国作为计算机的始祖国家,自然要推出一个这样的标准代码表。这就是美国信息交换标准代码,简称ASCII码表。这个码表包括了数字、英文大小写、符号、以及各种各样的转义字符,可以包含英文所用的全部功能。很快地,ASCII码称为了国际标准,现在大家知道的编码形式,都是与ASCII码兼容的。(图片来自:美国信息交换标准代码)
别的语言怎么办?UTF-8等其他编码方法
这个码表一出来,英语国家开心了…其他国家的脑袋疼了… 带注音的符号怎么办?日语韩语怎么办?最为博大精深的中文怎么办… 于是,各个国家也推出了本国语言的编码表。但是,为了能在计算机系统中通用,这些编码表基本都与ASCII码兼容。最为知名的就是UTF-8了。这个编码又称为万国码,顾名思义,就是支持包括中文简体、中文繁体、日语、韩语等各种语言的编码。这玩意太复杂了… 我就不细说了。
用一种编码形式打开另一种编码形式 会怎样?
既然每个国家都有自己的编码表了,问题也就来了。现在都国际化了,我要用一个支持本国语言的编码系统,打开另一个编码系统编码的文本,会出现什么情况呢?这就是乱码了… 更为严重的是,随着互联网的出现,各个国家的电脑都需要通信,而通信的一种方式就是使用URL地址。每个国家都希望把这个地址写成自己国家的语言。但这会导致其他国家根本没法访问地址,因为打不出这个字符嘛。所以,人类迫切需要一种中间编码形式,既能够兼容ASCII码,又能够把任意一种编码形式转换成只使用可读字符就能表示的编码。其中一种编码形式,就是Base64编码。
Base64编码,顾名思义,用64个可读字符进行编码。与Hex的16个字符相比多了很多,但是比ASCII码又少了一倍,去除了不可读字符。标准Base64编码中,这些字符是:
- 数字:0,1,2,3,4,5,6,7,8,9,共10个
- 小写字: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,共26个
- 大写字母: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,共26个加好+以及斜杠/
有的时候,根据不同的需要,Base64还有很多变种。比如,如果浏览器地址中用“+”和“/”的话,浏览器会将其转换为%XX的形式,又多了一步。因此可以将“+”和“/”换成“-”和“_”。
这种编码形式长度也短,效率也高。这样一来,数据通信的时候,不管来的是什么语言,都转化成Base64后再发送和接收。要是别国地址什么的打不出来,就直接打Base64编码形式就好了。如果细心的话,会发现百度云盘共享的时候,用的就是Base64。举个例子,前几天有个朋友给我发送一个视频,给的链接是这样的(后面四位略去):
http://pan.baidu.com/s/1gdH****
前面都是标准的网页形式,最后那个子文件,就是用Base64编码的,而且可以在任何通信工具中传递,方便快捷啊。
误区:Base64不是加密算法
很多博客什么的都把Base64当做加密算法,这是不对的。Base64不具有可读性,但不代表这个编码是加密的。加密需要保证,没有密钥的人无法解密信息,无法从密文中获得任何明文信息。Base64编码显然没有密钥什么事… 所以,这个误区大家要纠正过来。
读完刘学酥的答案,说下我的理解。
所有的信息本质上都是二进制的0和1,所以各种眼花缭乱的编码其实都是01组成的序列和字母符号汉字的对应关系。
比如 0100111100101010100011 这串二进制,在UTF-8里表示的是 “我是谁”。如果你想把“我是谁”转化成BASE64,你就要先把“我是谁”转化成“0100111100101010100011” 这串二进制,然后再把这串二进制转化成 “ZG0abd12" 的BASE64 编码。(上面的UTF8和BASE64表示都是举例)