首页 > 其他 > 详细

Base64

时间:2021-05-30 20:16:32      阅读:32      评论:0      收藏:0      [点我收藏+]

Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。可打印字符包括字母 A-Z、a-z、数字 0-9,这样共有 62 个字符,此外两个可打印符号在不同的系统中而不同。

由于以 2 为底 64 的对数为 6,所以以每 6 个比特为一个单元,对应某个可打印字符。3 个字节相当于 24 个比特,对应于 4 个 Base64 单元,即 3 个字节可由 4 个可打印字符来表示。

当下,Base64 常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及 XML 的一些复杂数据。

索引表

数值 字符 数值 字符 数值 字符 数值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

编码规则

接下来我们对“Man”进行编码,首先通过 ASCII 码表获取对应字符的二进制,并依次并排,然后从前往后每隔 6 位作为一个单元,根据上面的索引表得到对应的字符。

文本 M a n
ASCII编码 77 97 110
二进制位 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
索引 19 22 5 46
Base64编码 T W F u

如果要编码的字节数不能被 3 整除,最后会多出 1 个或 2 个字节,那么可以使用下面的方法进行处理:

  1. 先使用 0 字节值在末尾补足,使其能够被 3 整除;
  2. 然后再进行 Base64 的编码;
  3. 在编码后的 Base64 文本后加上一个或两个 = 号,代表补足的字节数。
文本(1 Byte) A
二进制位 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
二进制位(补0) 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Base64编码 Q Q = =
文本(2 Byte) B C
二进制位 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
二进制位(补0) 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
Base64编码 Q k M =

编解码

在 JavaScript 中,有两个函数被分别用来处理解码和编码 Base64 字符串:

  • atob() 函数能够解码通过 Base64 编码的字符串数据。
  • btoa() 函数能够从二进制数据“字符串”创建一个 Base64 编码的 ASCII 字符串。

以上面编码部分的例子为例:

btoa(‘Man‘); // "TWFu"
btoa(‘A‘); // "QQ=="
btoa(‘BC‘); // "QkM="

atob(‘TWFu‘); // "Man"
atob(‘QQ==‘); // "A"
atob(‘QkM=‘); // "BC"

按照设计,Base64 需要二进制数据作为其输入。就 JavaScript 字符串而言,这意味着如果将字符串传递到 btoa() 中,其中包含占用多个字节的字符,则会出现错误,因为这不被视为二进制数据:

btoa(String.fromCharCode(255)); // "/w=="
btoa(String.fromCharCode(256)); // error

如果需要使用 btoa() 将 Unicode 文本编码为 ASCII,一个选项是转换字符串,使每个 16 位单元只占用一个字节。例如:

function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i < codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}

// a string that contains characters occupying > 1 byte
const myString = ‘?‘;
const encoded = btoa(toBinary(myString));

如果您这样做,当你解码时也必须需要反转已解的码字符串。

Data URLs

在日常使用中,我们经常会通过 Data URLs 接触到 Base64 编码,Data URLs 是前缀为 data: 协议的 URL,其允许内容创建者向文档中嵌入小文件。

Data URLs 由四个部分组成:前缀(data:)、指示数据类型的 MIME 类型、如果非文本则为可选的 Base64 标记、数据本身:

data:[<mediatype>][;base64],<data>

如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,你就可以将数据进行 Base64 编码之后再进行嵌入。

比如我们可以借此实现图片预览:

<input id="fileEl" type="file" />
<script>
  fileEl.addEventListener(‘change‘, handleChange);

  function handleChange(ev) {
    const fileReader = new FileReader();
    const file = ev.target.files[0];

    fileReader.onload = handleLoad;
    fileReader.readAsDataURL(file); // 获取 DataURL
  }

  function handleLoad(ev) {
    const imgeEl = document.createElement(‘img‘);

    imgeEl.src = ev.target.result;
    document.body.appendChild(imgeEl);
  }
</script>

另外,还比较常见的情景就是我们在使用 Webpack 做优化时,可以通过 url-loader 在文件大小低于指定的限制时,可以返回一个 DataURL,借此减少不必要的 HTTP 请求。

来自其它数据

除了上面的例子外,Base64 还存在其它不少场景中,比如 HTMLCanvasElement.toDataURL() 方法也可以返回一个包含图片展示的 data URI:

canvas.toDataURL(type /* 图片格式 */, encoderOptions /* 图片的质量 */);

或者来自字节数组:

const btoa = (str) => Buffer.from(str, ‘binary‘).toString(‘base64‘);

或者 ...

Refs

Base64

原文:https://www.cnblogs.com/dongwanhong/p/14828563.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!