Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

base64 是什么? #37

Open
kangschampagne opened this issue Apr 24, 2018 · 0 comments
Open

base64 是什么? #37

kangschampagne opened this issue Apr 24, 2018 · 0 comments

Comments

@kangschampagne
Copy link
Owner

@kangschampagne kangschampagne commented Apr 24, 2018

在如今前端开发的过程中,必不可少的是对小图片进行 base64 的转化,那么你真的理解 base64 是什么吗?它的转换过程是什么?转换的结果有什么样的差别?
带着这三个问题,跟随笔者一一解答。

base64 是什么?

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于 2^6 = 64,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。

64 个可打印字符是哪些?
大小写拉丁字母 [A-Z][a-z] 26个、数字 [0-9] 10 个、加号 + 和斜杠 / ,共64个字符,等号 = 用来作为后缀用途。

我们先看,几个基础的计算机知识:
字节:Byte,计算机计量单位,部分数据类型。一个字节代表 8 个比特( bit )。
二进制:binary,以 2 为基数的技术系统表示的数字。
ASCII字符集由 95 个可打印字符(0x20-0x7E)和 33 个控制字符(0x00-0x19,0x7F)组成。wikipedia

所以上面那句话用人话说呢,base64 就是将一种编码转换成另外一种编码的结果

如下图栗子,3 个字节 就是 3*8=24 个比特(二进制位),6 个比特为一个 base64 单元,所以需要 4 个 单元来表示这 3 个字节。
image

为什么要将 Man 的 ASCII 对应的 二进制 转换成 由 6 个 bit 表示的 可打印字符呢?折腾?
其实这么编码的原因是为了数据传输而做的 编码转化

在计算机中任何数据都是按 ASCII 码存储的,而 ASCII 码的128~255之间的值是不可见字符。而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。

回到我们最初 base64 的例子 -- 邮件。
早期电子邮件的传输协议 SMTP 中,只支持ASCII 码字符。这个时候如果要传输一些图片声音等等,就没有办法实现了,所以就用 MIME标准 将二进制的内容编码成只包含 ASCII 字符的内容。

总结一句话就是,因为 ASCII 的不可见字符的存在,我们将这些也转换成可见字符,会利于传输降低出错可能性。同时也解决很多场景下,数据需要通过二进制传输的问题(数据只能通过简单通用的字符组成),比如邮件传输、HTTP协议中的请求头。

它的转换过程是什么?转换的结果有什么样的差别?

上面讲完了为什么需要 base64 ,那么如何转换呢,上图提供了简单的思路,当然还有一些如何解决补位的问题啊,详看 例子

因为 base64 将 二进制内容编码为 只包含 ASCII 字符的内容,如上可见,3 个字节 转变成 4 个字节,所以文件的尺寸会比原来增加 1/3 左右。为什么说左右呢,因为有一些补位,即不是3的整数倍时,bit数 / 3 的余数是 2 或者 1。

知道了 base64 原理,对以往做过项目中使用的场景也就能容易理解了。

习题:

  1. 如何将二进制数据编码为文本数据?

  2. 如何将一张图片二进制数据转换成 base64 编码数据?

  3. 浏览器又是如何根据 base64 源码还原成 二进制数据而显示图片?

解答

2.如何将一张图片二进制数据转换成 base64 编码数据?
笔者在前面关于 二进制文章中 提到 blob 对象,因此可用 File 对象进行转换。

var inputEl = document.getElementById('file')
inputEl.onchange = function (e) {
  var file = inputEl.files[0]
  if (!file) return

  var reader = new FileReader()
  reader.onload = function (e) {
    console.log('DataURL', e)
  }
  reader.readAsDataURL(file)

}

3.浏览器又是如何根据 base64 源码还原成 二进制数据而显示图片?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.