前端也要会“编码”知识,leader再也不用担心乱码问题了!!!

字符集

一组字符的集合,每个字符都有一个唯一的编号,称为码点。字符集的作用是将字符和码点一一对应起来,形成一个对照表。

ASCII

早期计算机起源于美国,ASCII 字符集是为英语设计的。共收录了 128 个字符,其中包括:可见字符(字母、数字、标点符号)和 控制字符(Tab、回车)。

GBK

ASCII 字符集无法兼容中文字符,为解决中文编码问题,设计出了 GBK 字符集,也被称为国标码,兼容 ASCII 字符集。GBK 共收录了 21886 个字符,包括汉字(部首、构件)和图形符号。

Unicode

为实现各国语言字符的互通,国际上设计出了Unicode 字符集,也被称为万国码,兼容 ASCII 字符集。它包含了3万多个字符。

Base64

由于 ASCII 字符集中包含控制字符,导致并非所有字符都是可见的。为了将二进制数据编码为可见的文本数据,Base64 字符集被提出。它包含 64 个字符,由大小写字母(A-Z、a-z)、数字(0-9)以及两个特殊字符(通常是"+"和"/")组成,再加上一个用于填充的"="字符。

编码

编码 是指将原始数据(如文本、图片)按照不同的 字符集 转换为二进制 数据。反过来,将二进制数据 转换回原始数据的过程被称为解码

UTF-8

最常见的编码方式,使用了Unicode 字符集进行转换字符,编码输出的二进制长度是1字节~4字节,也就是动态长度。

字符 码点 二进制
25105 01100010 00010001
i 105 01101001
20320 01001111 01100000

如果我们按照上面的二进制储存到文件中:

我i你 ==> 0110001000010001011010010100111101100000

这就遇到一个问题,如何去解析文件中的二进制串喃?因为UTF-8的自己是动态字节长度的。

当前字符需要解析多少个字节是未知的,比如:

前8位解析Unicode 字符是 b

前16位解析Unicode 字符是

前24位解析Unicode 字符是 错误!!

动态字节长度 是 UTF-8 的特点,也是他必须要解决的问题,所以 UTF-8 编码设置了一套二进制储存规范。

UTF-8编码「二进制」
0xxxxxxxx 1字节
110xxxxx 10xxxxxx 2字节
1110xxxx 10xxxxxx 10xxxxxx 3字节
11110xxx 10xxxxxx 10xxxxxx 4字节
字符 码点 二进制
25105 11100110 10001001 10000001
i 105 01101001
20320 11100100 10111101 10100000

我i你 ==> 11100110100010011000000101101001111001001011110110100000

虽然比原始的二进制串长,但是可以去按照开头的标识去解析二进制串了

UTF-32

前面聊到 UTF-8 的时候,不得不提到 UTF-32 。不过,UTF-32 出现得比 UTF-8 早,但后来却逐渐被淘汰了。

UTF-32 是一种固定字节的编码方式,不论字符在 Unicode 字符集中处于什么码点,都用 4 字节 来记录。这样做的好处是字符表示简单直接,能涵盖所有 Unicode 字符,还避免了像 UTF-8 那样需要识别字节前缀的复杂性。

但它的缺点也很明显,那就是太占空间了。每个字符都用 4 字节,即使是简单的 ASCII 字符也不例外,这在存储和传输大量文本时,会带来很大的资源浪费。

所以,尽管 UTF-32 在某些特定场景下仍有其价值,但整体上,它还是因为效率和资源占用的问题,逐渐被 UTF-8 等编码方式取代了。

Base64

Base64编码 是一种将数据转换为可打印字符的编码方式,常用于文件、字符串等数据的可视化传递

  • 使用 64个字符(包括大小写字母、数字和特殊符号)作为字符集,确保所有字符都是可视的。

解码

  • 解码 时,以 6位 二进制为一组进行分割。如果最后的二进制数量不足 6位 ,则进行补 0
  • 解码 成功时,判断 Base64 长度是否能被 4 整除,如果不足 4 个字符,就进行补 =
js 复制代码
// 定义Base64字符集
const base64CharSet = {};

// 初始化Base64字符集,将索引与字符对应
`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=`.split("").forEach((char, index) => base64CharSet[index] = char);

/**
 * 将字符串转换为Base64编码
 * @param {string} inputStr - 需要转换的字符串
 * @returns {string} Base64编码后的字符串
 */
function stringToBase64(inputStr) {
    // 用于存储最终的Base64编码结果
    let base64String = "";

    // 将输入字符串的每个字符转换为对应的ASCII码的二进制表示,并拼接成一个长的二进制字符串
    // 注意:每个字符的二进制表示需要补足8位
    let binaryString = inputStr.split("").map(char => {
        return char.charCodeAt().toString(2).padStart(8, '0');
    }).join("");

    // 如果二进制字符串的长度不是6的倍数,则在末尾补0,使其长度成为6的倍数
    if (binaryString.length % 6 !== 0) {
        binaryString += "0".repeat(6 - binaryString.length % 6);
    }

    // 遍历二进制字符串,每6位一组进行处理
    for (let index = 0; index < binaryString.length; index += 6) {
        // 提取每6位二进制字符
        let sixBitSegment = binaryString.substring(index, index + 6);

        // 将6位二进制字符转换为十进制索引
        let indexInBase64Set = parseInt(sixBitSegment, 2);

        // 根据索引从Base64字符集中获取对应的字符,并添加到结果中
        base64String += base64CharSet[indexInBase64Set];
    }

    // 如果Base64编码结果的长度不是4的倍数,则在末尾补"="字符
    if (base64String.length % 4 !== 0) {
        base64String += "=".repeat(4 - base64String.length % 4);
    }

    // 返回最终的Base64编码字符串
    return base64String;
}

// 测试代码
console.log(stringToBase64("hello world")); // 输出Base64编码结果
相关推荐
该用户已不存在5 分钟前
8个Docker的最佳替代方案,重塑你的开发工作流
前端·后端·docker
然我6 分钟前
面试官最爱的 “考试思维”:用闭包秒杀递归难题 🚀
前端·javascript·面试
明月与玄武14 分钟前
HTML知识全解析:从入门到精通的前端指南(上)
前端·html
teeeeeeemo29 分钟前
CSS place-items: center; 详解与用法
前端·css·笔记
未来之窗软件服务33 分钟前
html读取身份证【成都鱼住未来身份证】:CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构
前端·html·身份证读取
木木jio38 分钟前
🧹 前端日志查询组件的重构实践:从 1600 行巨型组件到模块化 hooks
前端·react.js
WAKEUP3691 小时前
TypeScript 类型系统简述:构建更健壮的代码基础
前端·typescript
難釋懷1 小时前
Vue-github 用户搜索案例
前端·vue.js