Base64编码知识详解

我们在做前端开发的时候,为了项目优化,经常会提到一个:对于较小的图片,合理使用字符串代替可以减少页面http请求。

而且还会强调一定是小图,大小不能超过几KB等等。

那是什么?

初步了解

下面的字符串应该是每个人都通用的。通过这种固定的格式,一张图片被浏览器表示和识别,图片就可以完整的展示出来:

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......

这是一个svg格式的图片,当然我们也可以加载浏览器支持的任何格式的图片。

这个字符串是基于编码的,后面的长字符串就是编码后的字符串。

它是如何诞生的

电子邮件是互联网早期最有效的应用程序。

早期电子邮件的 SMTP 传输协议只能用于传输 7 位的 ASCII 码,而 ASCII 码是基于英文设计的,因此来自非英语国家的文本等资源可以不发送。

为了解决这个问题,一般互联网邮件扩展了MIME,增加了邮件的主体结构,定义了非ASCII码的编码传输规则。

字符编码的知识请参考前端开发需要了解的字符编码知识

基本定义

它是基于64个可打印字符来表示二进制数据的编码和解码方法。

因为它可以编码和解码,所以它的主要作用不是安全,而是让内容在各个网关之间无误传输。

64 个可打印字符包括大写字母 A-Z、小写字母 a-z、数字 0-9(共 62 个字符)以及另外 2 个 + 和 /。

是一个索引码,每个字符对应一个索引,具体关系图如下:

这也是名字64的由来。

编码

由于64等于2的6次方,所以一个字符实际上代表6个二进制位(bit)。

但是,1个字节(byte)的二进制数据对应8个比特(bit),所以3个字节(3 x 8 = 24 bits)的字符串/二进制数据正好可以转换成4个字符(4 x 6 = 24位)。

为什么是一组3个字节?由于 6 和 8 的最小公倍数是 24,所以 24 位正好是 3 个字节。

具体编码方式:

以每3个字节为一组,3个字节共有24个二进制位。这 24 个二进制位分为 4 组。每组有6个二进制位,每组6个二进制位前面加两个00展开成32个二进制位,即4个字节的每个字节对应一个小于64的数,即一个人物。然后根据字符索引关系表来编号,每个字符编号对应一个字符,得到编码后的字符。

上图中的字符串’you’,转换后得到的代码为:’eW91’。

音量增加

我们可以看到,当3个字符经过转换和编码后,最终变成了4个字符。因为每个 6-bit 填充了 2 个 0,变成了 8-bit,对应 1 个字节。

这正好多出三分之一,所以在正常情况下,编码后的数据量通常比原始数据量大三分之一。

这也是我们在使用编码优化图片时需要强调小图标的原因。如果所有图片都使用这种方法,静态文件会增加很多,不适合。

= 等号

图片[1]-Base64编码知识详解-唐朝资源网

3个英文字符可以精确转换成4个字符。那么如果字符长度不是3的倍数应该使用什么规则呢?

其实很简单。我们实际使用Base编码的时候,经常会发现第65个字符的存在,也就是’=’符号。这个等号是处理这种特殊情况的一种方式。 .

对于小于3字节的地方,实际上会在后面加0,直到有24个二进制位。

但是需要注意的是,在计算字节数的时候,总长度会直接除以3,如果余数为1,则直接在末尾加一个=,如果余数为2,则加两个=。

因此,转码后的字符串需要补充一个后缀等号,可以是1也可以是2,如下图所示:

@ >

图中第二个使用单独的字符’d’来区分索引字符表中的索引0。这时候在得到的代码中,会有一个A对应索引0的字符,’=’就是直接加2。

非 ASCII 字符

由于只能编码ASCII字符,如果是汉字等非ASCII字符,需要先将汉字转换为ASCII字符再进行。编码即可。

编解码器方法 btoa 和 atob

提供了两种处理编码的原生方法:btoa() 和 atob()。

btoa('you') // 'eW91'
atob('eW91') // 'you'

btoa('中') // Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.
atob('y') // Uncaught DOMException: The string to be decoded is not correctly encoded.

图片[2]-Base64编码知识详解-唐朝资源网

处理汉字

因为btoa和atob只支持ASCII字符编码,也就是单字节字符,而我们平时的中文是2-4字节的字符。

因此,可以先将汉字转为utf-8编码,将utf-8编码作为字符使用,这样就可以对多个单字节字符进行编码了。

中文有两种方法:()和()。

如下,中文编解码方式:

window.btoa(encodeURIComponent('中国'))
// 'JUU0JUI4JUFEJUU1JTlCJUJE'
decodeURIComponent(window.atob('JUU0JUI4JUFEJUU1JTlCJUJE'))
// '中国'

第三方库前端常用应用

接下来,我们了解一下前端开发中编码的一些常见使用场景。

在前端应用中,大多是针对图片的处理,一般都是基于方法使用的。

数据URL由数据组成:前缀、MIME类型(表示数据类型)、标志位(如果是文本,可选)和数据本身。

具体格式:data:[][;],.

这里的第四部分,数据本身,是一个字符串。

小图转码

也就是开头提到的图片优化,使用可以减少请求次数,可以在img标签下,也可以在css中:

图片[3]-Base64编码知识详解-唐朝资源网

.icon {
  background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==);
}

我们在使用vue或者react框架的时候,也可以通过url-来配置,图标旋转的大小:

  .loader('url-loader')
  .tap(options => {
    options.limit = 10240 // 10kb
    return options
  })

图片[4]-Base64编码知识详解-唐朝资源网

文件读取

在Web环境中,提供了一个API来读取文件的数据。将文件数据读取为编码字符串数据:

  let reader = new FileReader()
  reader.onload = () => {
    let base64Img = reader.result
  };
  reader.readAsDataURL(file)

此方法常用于图片上传。

生成图像

本质上是一个位图图片,有一个()方法导出画布生成图片,会以编码格式保存。

const dataUrl = canvasEl.toDataURL()
// data:image/png;base64,PHN2ZyB4bWxucz0iaHR0c......

其他

除了处理图片,还会用到特殊的数据传输,简单的编码和加密,代码混淆,以及一些证书。 ,请参阅编码字符串。

总结

最后总结一下特点:

© 版权声明
THE END
喜欢就支持一下吧
点赞151 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片