何为Base64算法
Base64是一种基于64个字符的编码算法,根据RFC2045的定义:“Base64内容传送编码是一种以任意8位字节序列组合的描述形式,这种形式不易被人直接识别”。经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。经Base64编码后的字符串的字符数是以4为单位的整数倍。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME的电子邮件及XML的一些复杂数据。
Base64是网络上最常见的用于传输8Bit字节码的可读性编码算法之一 可读性编码算法不是为了保护数据的安全性,而是为了可读性
可读性编码不改变信息内容,只改变信息内容的表现形式 所谓Base64,即是说在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/”
Base58是Bitcoin(比特币)中使用的一种编码方式,主要用于产生Bitcoin的钱包地址
相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+"和"/"符号
Base64 算法原理
在不同的实现中,Base64算法中由64个字符组成的字符集是不一样的。但是通常的实现方法是选择64个通用且能打印的字符来组成这样一个集合。且要保证这个集合中的每个字符组成的数据在数据传输系统中不会被修改。
base64 是 3个字节为一组,一个字节 8位,一共 就是24位 ,然后,把3个字节转成4组,每组6位,
3 * 8 = 4 * 6 = 24 ,每组6位,缺少的2位,会在高位进行补0 ,这样做的好处在于 ,base取的是后面6位,去掉高2位
,那么base64的取值就可以控制在0-63位了,所以就叫base64,111 111 = 32 + 16 + 8 + 4 + 2 + 1 =
base64 构成原则
① 小写 a - z = 26个字母
② 大写 A - Z = 26个字母
③ 数字 0 - 9 = 10 个数字
④ + / = 2个符号
大家可能发现一个问题,咱们的base64有个 = 号,但是在映射表里面没有发现 = 号 , 这个地方需要注意,等号非常特殊,因为base64是三个字节一组
,如果当我们的位数不够的时候,会使用等号来补齐
实现原理
Base64算法主要是对给定的字符以与字符编码(如ASCII码,UTF-8码)对应的十进制数为基准,做编码操作:
* 将给定的字符串以字符为单位,转换为对应的字符编码(如 ASCII 码);
* 将获得的字符编码转换为二进制编码;
*
对获得的二进制码做分组转换操作,每3个8位二进制码为一组,转换为每4个6位二进制码为一组(不足6位时低位补0)。这是一个分组变化的过程,3个8位二进制码和4个6位二进制码的长度都是24位(3×8=4×6=24);
* 对获得的4个6位二进制码补位,向6位二进制码添加2位高位0,组成4个8位二进制码;
* 将获得的4个8位二进制码转换为十进制码;
* 将获得的十进制码转换为Base64字符表中对应的字符。
对字符串“A”进行Base64编码,如下所示:
* 字符 A
* ASCII码 65
* 二进制码 01000001
* 4-6二进制码 010000 010000(补足4个0)
* 4-8二进制码 00010000 00010000
* 十进制码 16 16
* 字符表映射码 Q Q = =
由此,字符串“A”经过Base64编码后就得到了“QQ==”这样一个字符串。
经Base64编码后的字符串最多只会有2个等号,这是因为:
余数 = 原文字节数 mod 3
这是一个简单的算术问题,余数的值只可能是0、1或2。余数为0时,则原文字节数恰好是3的倍数,没有等号这个尾巴;余数为1时,则为了让Base64编码后的字符数是4的倍数,要补2个等号;同理,余数为2时,则要补1个等号。所以,通常判别一个字符串是不是Base64编码的第一步操作就是判断这个字符串末尾是不是有等号。
这同时也说明,Base64编码后的字符串是以4个字符为单位,其长度只能是4个字符的整数倍。
非ASCII码字符编码
Base64算法很好地解决了非ASCII码字符的传输问题,譬如中文字符的传输问题。
ASCII码可以表示十进制范围为0~127的字符,对应二进制范围是0000 0000~0111
1111。ASCII码包括阿拉伯数字、大小写英文字母和一些控制符,但却没有包含双字节编码的字符,如中文字符。因此有了GB2312、GBK和UTF-8等编码。GB2312、GBK用2个字节表示一个汉字,UTF-8编码则用3个字节表示一个汉字。Base64算法实现时,对6位二进制码添加高2位0,恰恰保护了非ASCII码字符在通过有问题的网关时不发生问题。
以字符串“密”为例,字符串“密”对应的UTF-8编码就是-27,-81,-122。对其做如下Base64编码:
* 字符 密
* UTF-8码 -27 -81 -122
* 二进制码 11100101 10101111 10000110
* 4-6二进制码 111001 011010 111110 000110
* 4-8二进制码 00111001 00011010 00111110 00000110
* 十进制码 57 26 62 6
* 字符表映射码 5 a + G
字符串“密”经过Base64编码后得到字符串“5a+G”。
当然,如果使用GBK编码就不是这个结果了!字符串“密”对应的GBK编码是-61,-36,经过Base64编码后就是字符串“w9w=”了。
应用场景
* 电子邮件传输
* 网络数据传输
* 密钥存储
* 数字证书存储
* OpenSSL操作Base64编码