10分钟快速掌握Base64的编码原理和过程

310 阅读9分钟

Base64是什么?

  1. Base64是一种将二进制数据以文本形式表示的编码方式。
  2. Base64编码使用6个二进制位来表示一个字符,6个二进制位刚好可以表示64个不同的字符。
  3. 其中包括26个大写字母( A - Z ),26个小写字母( a - z ),10个数字( 0 - 9 )以及加号( + )和斜线( / )这两个特殊字符。
  4. Base64编码的主要目的是在不破坏数据的情况下,将二进制数据转换为纯文本格式,方便在文本环境中传输和处理。由于Base64编码的字符集是标准ASCII字符,它可以在各种系统和环境中进行可靠的传输,而不受特殊字符对传输的影响。
码值字符码值字符码值字符码值字符
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

Base64编码的原理

编码的原理可以分为三个步骤:

  1. 把要编码的字符串转成二进制的形式。
  2. 把这个二进制的字符串按照每六位一组来分组,如果最后一组的二进制位不足6位的话需要用0来补齐。
  3. 把每一组的二进制位转换成十进制的数字,并到Base64编码表中找到对应的字符。

注意:编码之后的长度需要是4的倍数,如果不是的话就需要在结尾用等号来补齐。相应的,解码的过程也就是把编码的过程反过来就可以。

HelloWorld字符串转Base64格式的编码过程

步骤1:( 把要编码的字符串转成二进制的形式

在ASCII编码中,大写字母 "H" 的十进制表示为 72。对应的二进制位是 01001000。

在ASCII编码中,小写字母 "e" 的十进制表示为 101。对应的二进制位是 01100101。

在ASCII编码中,小写字母 "l" 的十进制表示为 108。对应的二进制位是 01101100。

在ASCII编码中,小写字母 "l" 的十进制表示为 108。对应的二进制位是 01101100。

在ASCII编码中,小写字母 "o" 的十进制表示为 111。对应的二进制位是 01101111。

在ASCII编码中,大写字母 "W" 的十进制表示为 87。对应的二进制位是 01010111。

在ASCII编码中,小写字母 "o" 的十进制表示为 87。对应的二进制位是 01101111。

在ASCII编码中,小写字母 "r" 的十进制表示为 114。对应的二进制位是 01110010。

在ASCII编码中,小写字母 "l" 的十进制表示为 108。对应的二进制位是 01101100。

在ASCII编码中,小写字母 "d" 的十进制表示为 100。对应的二进制位是 01100100。

步骤2:( 把这个二进制的字符串按照每六位一组来分组,如果最后一组的二进制位不足6位的话需要用0来补齐

01001000 - 01100101 - 01101100 - 01101100 - 01101111 - 01010111 - 01101111 - 01110010 - 01101100 - 01100100

010010 000110 010101 101100 011011 000110 111101 010111 011011 110111 001001 101100 011001 00 此处不足6位要补0

最终为:010010 000110 010101 101100 011011 000110 111101 010111 011011 110111 001001 101100 011001 000000

步骤3:( 把每一组的二进制位转换成十进制的数字,并到Base64编码表中找到对应的字符

  1. 010010 -> 18 -> Base64编码表对应 S
  2. 000110 -> 6 -> Base64编码表对应 G
  3. 010101 -> 21 -> Base64编码表对应 V
  4. 101100 -> 44 -> Base64编码表对应 s
  5. 011011 -> 27 -> Base64编码表对应 b
  6. 000110 -> 6 -> Base64编码表对应 G
  7. 111101 -> 61 -> Base64编码表对应 9
  8. 010111 -> 23 -> Base64编码表对应 X
  9. 011011 -> 27 -> Base64编码表对应 b
  10. 110111 -> 55 -> Base64编码表对应 3
  11. 001001 -> 9 -> Base64编码表对应 J
  12. 101100 -> 44 -> Base64编码表对应 s
  13. 011001 -> 25 -> Base64编码表对应 Z
  14. 000000 -> 0 -> Base64编码表对应 A

注意:此处只有14项,编码之后的长度不满足4的倍数,需要在结尾用等号来补齐。

所以最终的结果为:SGVsbG9Xb3JsZA==

JavaScript手写Base64转换

const example = 'HelloWorld'

function toBinary (str) {
    let binaryResult = ''
    for (let i = 0; i < str.length; i++) {
        // 获取每个字符的 Unicode 编码
        // 其 Unicode 编码单元值与 ASCII 编码是相同的。
        // ASCII 编码规范只包含 7 位,而 Unicode 编码使用 16 位,其中前 128 位(0-127)与 ASCII 完全相同。
        const charCode = str.charCodeAt(i)
        // 将 Unicode 编码转换为二进制表示
        const binaryChar = charCode.toString(2).padStart(8, '0')
        binaryResult += binaryChar
    }
    return binaryResult
}
const binaryStr = toBinary(example)

function splitAndPadEnd (binaryStr) {
    let str = ''
    if (binaryStr.length % 6 !== 0) {
        // 使用 padEnd 在字符串末尾添加0,确保长度是6的倍数
        str = binaryStr.padEnd(Math.ceil(binaryStr.length / 6) * 6, '0')
    } else {
        str = binaryStr
    }
    // 使用 match 方法和正则表达式来按照6位分割字符串
    return str.match(/.{6}/g)
}
const coding = splitAndPadEnd(binaryStr)

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

function codingToBase64 (coding) {
    // 原Base64字符串
    const originBase64 = coding.reduce((base64, item) => {
        // 将字符串转换为十进制
        const decimal = parseInt(item, 2)
        // 将十进制转换为base64
        const chars = base64Mapping[decimal]
        return base64 + chars
    }, '')
    if (originBase64.length % 4 !== 0) {
        // 补全Base64字符串
        return originBase64.padEnd(Math.ceil(originBase64.length / 4) * 4, '=')
    }
    return originBase64
}
const base64 = codingToBase64(coding)
console.log(base64)

btoa和atob

btoa 和 atob 是 JavaScript 中用于进行 Base64 编码和解码的两个内置函数。它们分别用于将二进制数据编码为 Base64 字符串(btoa),以及将 Base64 字符串解码为原始的二进制数据(atob)。

注意:btoaatob 主要用于处理纯文本数据,而不是二进制数据。如果你需要处理二进制数据,应该使用更先进的方法,如 BlobArrayBuffer 等。

// 编码字符串
const encodedData = btoa("HelloWorld")
console.log(encodedData, 'encodedData') // SGVsbG9Xb3JsZA==

// 解码字符串
const decodedData = atob(encodedData)
console.log(decodedData, 'decodedData') // HelloWorld

Base64的应用场景有哪些?(回答来源于ChatGPT3.5)

  1. 数据传输: 在网络上传输数据时,某些二进制数据(例如图片、音频、视频等)可能包含不可见字符或特殊字符,可能会导致传输错误。通过使用 Base64 编码,可以将二进制数据转换为文本数据,确保数据的安全传输。
  1. HTML/CSS 中的图片嵌入: 在 HTML 或 CSS 中,可以使用 Base64 编码将图片嵌入到代码中,而不需要额外的网络请求。这可以减少页面加载时的请求次数,提高性能。
  1. 数据存储: 在一些情况下,将二进制数据编码为 Base64 字符串可以方便地存储在文本文件或数据库中,而无需处理二进制数据的复杂性。
  1. 电子邮件附件: 在电子邮件中,Base64 用于编码附件文件,确保文件以文本格式传输,适用于电子邮件协议。
  1. 加密签名: 在一些加密算法中,Base64 用于对二进制数据进行编码,以便在数字签名等场景中传输和显示。
  1. 数据URL: 在浏览器中,Base64 编码用于将小图片转换为数据URL,以减少对服务器的请求。
  1. 配置文件: 在一些配置文件或数据格式中,Base64 用于编码二进制数据,使其更容易嵌入和处理。
  1. 身份验证: 在一些身份验证机制中,Base64 编码用于传输和存储用户凭证信息。