Base64简介

最近开发过程当中常常会须要Base64编码,MD5,加密等功能,这些频繁使用的小工具要常常到网上找,并且还都不太好用,就本身开发了一个, codoolo。在实现Base64的过程,也学到了不少。这篇文件记录Base64相关的知识,欢迎指正。

Base64是什么?

Base64早已经被普遍使用了,尤为是Multipurpose Internet Mail Extensions (MIME)。html

wikipedia中对Base64的定义:安全

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation.

简单来讲,Base64使用了指定的64个字符对数据编码,而这64个字符中不包括特殊字符(以避免被一些应用认为是控制字符,若是ftp,ssh等),这样通过编码的数据能够在网络中安全的传输。网络

如何实现Base64?

首先须要挑选64个字符。RFC 4648定义了Base64的字符集:ssh

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/工具

下图显示如何将字符串“xyz”编码为“eH16”的过程编码

steps to encode 3 chars

步骤:

  1. 把每一个字符转换为整数,也就是字符在ASCII中的位置
  2. 将整数转换为二进制表示
  3. 每六位一组,转为整数,并在上面的Base64字符集中找到该整数所在位置的字符
  4. 将获得的字符链接起来,获得最终的结果

第二步和第三步实际上是一系列位操做,并不须要真的转换,这里为了将编码过程阐述清楚,加了这两个步骤。加密

因为6位正好能够表示64,因此每3个8位的字符(24bit)能够编码为4个Base64字符(4个6bit=24bit)。但编码后的每一个字符的存储仍然须要8位。这意味着Base64编码后的存储空间增长了1/3spa

由此认识到:

Base64使用6 bits重组数据,但重组后的每一个字符仍然须要8 bit的存储空间。因此Base64是用较小的字符集表示数据,但存储空间却所以增长了,所谓有一利必有一弊。code

URL和文件名

在上面的Base64字符集中包括了 '+/' ,而通常的URL和文件名中,不能使用这两个字符,因此RFC4686提议使用另一个字符集:orm

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_

而具体用哪一个字符集,要考虑使用的场景。好比只是在项目内部使用,编解码均可控,那么就可使用第二个,甚至可使用一个自定义的字符集。但若是是将数据给第三方,那么使用第一个字符集更好,由于大部分库的实现都使用了第一个字符集。

若是数据的长度不是3的倍数怎么办?

咱们刚刚说了如何将3个字符应用Base64编码,但若是字符串的长度不是3的倍数怎么办?

若是最后还有两个字符须要编码:
steps to encode 2 chars

好比"xy",2个字符有16 bits,那么前12 bits能够编码为"eH",对于剩下的4 bits,在右侧填充2个0,因此第三个字符是"k"。有时,网络中传输的数据长度是未知的,这时为了肯定知道数据是否截止,则须要将编码的数据补齐为4的倍数。对于Base64编码,使用 = 来补齐,也就是第65个字符

若是最后只有一个字符,过程相似:

steps to encode 1 char

须要注意的是,最后使用了2个 == 来补齐。

请问,若是一个Base64编码的最后有3个=,即===,这是一个合法的Base64编码么?

若是数据不是ASCII码呢?

咱们上面讨论编码的时候,都假设输入的是ASCII,即字符是0x00-0xFF之间的。那若是输入的字符是UTF-8呢?好比:

“こんにちは” 或者 “你好”

通常有两种方式来处理:

  • 在编码前转义字符串
  • 将UTF-8转为bytes

因此在实现codoolo时, 若是输入的是非ASCII码,会提示选择一个转换器:

show converter for non ASCII

如何解码?

了解了编码过程,相信解码就比较简单了,也就是将上面的过程逆向执行就能够。

还有什么?

说实话,我一直在使用Base64编码,到从没想过一个Base64编码也要有这么多须要注意的地方,并且还有问题:

  • 当将汉字等编码后,在解码时若是直接输出汉字?
  • Base64使用了更多的存储空间,那么是否是可使用Base128呢?
  • 若是我使用一个特殊的字符集,这样编码出来的数据有多安全?容易破解么?
  • 如何提升编解码的效率?

咱们之后接着聊。

相关文章
相关标签/搜索