前言
上篇文章有涉及到Base64编码的内容,今天我们再来详细了解一下Base64的编码原理以及应用场景。
通过这篇文章你能够学习到:
- 什么是Base64,为什么需要Base64?
- Base64的编码原理
- Base64的应用场景
什么是Base64?
Base64是一种用于传输8bit字节数据的编码方式,Base64 的字符集包含 64 个字符(A-Z、a-z、0-9、+、/)以及补位的=
⚠️需要注意的是它只是一种编码方式,并不是加密方式!!!因为对于Base64来讲,它没有密钥的概念,这意味着任何人都能轻松地将Base64编码的数据还原为原始字符。
尽管如此,不少人仍误将其当作加密工具来使用,这在具备基本技术知识的人眼中,无异于未加密处理...
为什么需要Base64编码?
Base64编码最初主要应用于邮件传输协议中,由于这些协议仅支持ASCII字符的传递,导致直接传输二进制文件(如图片、视频等)成为不可能。为了解决这一问题,Base64被设计出来,它能够将二进制文件内容转换成仅包含ASCII字符的编码形式,从而实现在邮件传输协议中安全、有效地传递二进制数据。
编码原理
Base64 编码的核心原理是将输入数据(多为二进制形式)转换成特定字符序列。具体步骤为:首先将输入数据分割成每三个字节(共24位)一组,接着将这24位分割为四个6位的块(因为Base64中每个字符代表6位二进制数据)。最后,通过查找表将这些6位块映射为相应的Base64字符。
base64字符集
上面我们提到标准的Base64一般包含64个字符再加一个补位的=
- 大写字母:A-Z(26 个字符)
- 小写字母:a-z(26 个字符)
- 数字:0-9(10 个字符)
- 特殊字符:+ 和 /(2 个字符)
- 补位字符:=
编码步骤
- 分组:将输入数据按每三个字节一组进行划分,每组组成一个24位的二进制数据块。
- 分割:将每个24位的数据块进一步分割成四个6位的数据块。
- 字符映射:通过查找字符集,将每个6位数据块映射为字符集中的对应字符。
- 填充处理:若输入数据的字节数非3的倍数,则在数据末尾添加=字符作为填充,以确保编码结果的长度符合Base64规范。
怎么理解这些步骤?
以南玖的南拼音为例
首先将字符对应的二进制位表示出来
刚好nan是3个字节,它们的二进制位正好组成了一个24位的二进制块
接着把这个二进制块分割成4个6位的数据块
最后通过查找Base64编码对照表,找到每个6位数据块对应的字符
最终nan编码为bmFu
由于nan的字节数正好是3的倍数,所以它不需要补位,编码后也就不会出现=
补位
如果字节数不是3的倍数,那么余数可能是1或2,所以补位也需要分两种情况。
- 余数为1,二进制末尾补4个0,最后多出来的这个字符会编码成2个base64字符,最后再补两个=
比如宋的拼音song,余数为1
在这基础上最后还得补上2个=,最终song编码为c29uZw==
- 余数为2,二进制末尾补2个0,编码后末尾再补1个=
比如ab,余数为2
最终ab编码为YWI=
验证
在javaScript中可以调用btoa来进行base64编码
动手实现一下Base64编解码
base64编码
- // 自定义base64编码
- const customEncrypt = (str: string) => {
- // base64字符集
- const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
- // 将字符串转中的每个字符转换成8位二进制
- const binaryStr = str.split('').map(char => {
- const binary = char.charCodeAt(0).toString(2)
- return binary.padStart(8, '0')
- }).join('')
-
- // 将二进制字符串按6位分割
- const binaryArr = binaryStr.match(/.{1,6}/g) || []
-
- // 如果最后一组不是6位的倍数,后面补0
- const last = binaryArr[binaryArr.length - 1]
- if(last?.length % 6 !== 0) {
- binaryArr[binaryArr.length - 1] = last.padEnd(6, '0')
- }
-
- // 将6位的二进制转换成10进制
- const decimalArr = binaryArr.map(binary => parseInt(binary, 2))
-
- // 根据10进制的值获取base64字符
- let base64Str = decimalArr.map(decimal => base64Chars[decimal]).join('')
-
- // 补位
- while(base64Str.length % 4 !== 0) {
- base64Str += '='
- }
- return base64Str
- }
复制代码 基本按照上面的编码步骤实现即可
验证- console.log('btoa', btoa('song'))
- console.log('自定义编码', customEncrypt('song'))
复制代码
base64解码
解码的过程基本就是与编码反过来- // 自定义base64解码
- const customDecrypt = (str: string) => {
- // base64字符集
- const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
- // 将base64字符转换成10进制
- const decimalArr = str.split('').map(char => base64Chars.indexOf(char))
-
- // 将10进制转换成6位二进制
- const binaryArr = decimalArr.map(decimal => decimal.toString(2).padStart(6, '0'))
-
- // 将6位的二进制拼接
- const binaryStr = binaryArr.join('')
-
- // 将8位的二进制转换成字符
- const charArr = binaryStr.match(/.{1,8}/g) || []
- return charArr.map(binary => String.fromCharCode(parseInt(binary, 2))).join('')
- }
复制代码 验证- console.log('atob', atob('c29uZw=='))
- console.log('自定义解码', customDecrypt('c29uZw=='))
复制代码
思考
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |