脚本宝典收集整理的这篇文章主要介绍了学习笔记—编码的发展,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
日常的学习笔记,包括 ES6、Promise、Node.js、Webpack、http 原理、Vue全家桶,后续可能还会继续更新 TyPEscript、Vue3 和 常见的面试题 等等。
我们现在常用的编码是 ASCII
编码,汉字都是使用 UTF-8
格式。
编码一般分为以下几种
ASCII码 的八位字节可以表现出 256 种不同的形态。
0-32 规定了特殊用途,一旦终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。(如 遇上0×10, 终端就换行。遇上0×07, 终端就会发出嘟嘟嘟的声音 等。)
所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第 127 号。这样计算机就可以用不同字节来存储英语的文字了。
因为计算机最早是在美国进行使用的,而他们也只使用了前 127 号。但是世界上存在那么多种语言,光是汉语就有好几万个汉字,这种编码格式显然是不太行的。
西欧一些国家用的不是英文,所以他们使用 127 号这后的空位来保存新的字母,一直编到了最后一位 255。(不同国家表示的符号也是不同的,130 在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג))
而我们国家为了表示汉字,把 127 之后的符号取消了。
一个 小于127 的字符的意义与原来相同。但两个大于 127 的字符连在一起时,就表示一个汉字。前面的一个字节(高字节)从 0xA1
到 0xF7
,后面一个字节(低字节)从 0xA1
到 0xFE
。这种方式可以组合出大概 (247-161)*(254-161) = 7998
多个简体汉字。
而 数学符号、日文假名 和 ASCII里原来就有的 数字、标点 和 字母 都重新编成两个字长的编码。这就是 全角字符,127 以下那些就叫半角字符。
这种汉字方案叫做 GB2312
。GB2312
是对 ASCII
的 中文扩展 。
在使用过程中,发现 GB2312
还是不够用。于是便不再要求 低字节 一定是 127 之后的内码,只要第一个字节是大于 127 ,就固定表示这是一个汉字的开始。
于是又增加了近 20000 个新的汉字(包括繁体字)和符号。
GBK
扩成了GB18030
通称他们叫做 DBCS,增加了几千个新的少数民族的字。
在 DBCS 系列标准里,最大的特点是 两字节长的汉字字符 和 一字节长的英文字符 并存于同一套编码方案里。
就这样,各个国家都搞出了一套自己的编码标准。就导致会同时存在好多种不同的编码,互相之间不支持也不互通。
Unicode
编码,开发人员应该并不陌生。
ISO:International organization for Standardization ,国际标准化组织
Unicode:Universal Multiple-octet Coded Character Set ,简称 UCS,俗称 Unicode
ISO 的国际组织废了所有的地区性编码方案,重新搞一个包括了地球上 所有文化、所有字母 和 文字 的编码。
Unicode
是一个很大的集合,现在的规模可以容纳 100多万 个符号。
ISO 组织直接规定必须用 两个字节(16位) 来表示所有的字符。ASCII
里的那些 半角字符,Unicode
保持其原编码不变,只是将其长度由原来的 8 位扩展为16 位,而其他文化和语言的字符则全部重新统一编码。
从 Unicode
开始,无论是半角的 英文字母,还是全角的 汉字,它们都是统一的一个字符。同时,也都是统一的 两个字节。
Unicode
在很长一段时间内无法推广,直到互联网的出现。
为解决 Unicode
如何在 网络上传输 的问题,面向传输的众多 UTF
标准出现了。
UTF编码:Universal Character Set(UCS)transfer Format
UTF-8
就是在互联网上使用最广的一种 Unicode
的实现方式。
UTF-8
是每次以 8位 为单位进行数据传输,而 UTF-16
是每次以 16位 进行传输的。
UTF-8
是一种变长的编码方式。Unicode
一个中文字符占 2 个字节,而 UTF-8
一个中文字符占 3 个字节。
换言之,UTF
就是 Unicode
的另一种实现方式。
Base64
是网络上最常见的用于传输 8位 字节码的编码方式之一。开发中可以替换掉路径,而且可以用于传输。
Base64
编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用 Base64
编码具有不可读性,需要解码后才能阅读。
Base64
要求把每 三个8位 的字节转换为 四个6位 的字节,然后把 6位 再添两位高位0,组成 四个8位 的字节。
我们平时会使用 encodeURIcomponent()
方法将文字转换成 16进制。
我们都知道,一个字 3字节,一个字节 8 位 。而 Base64
其实就是将一个汉字转换为 3 * 8 = 4 * 6
的格式,也就是说现在一个汉字会有 4个字节 的长度,转换后的结果会比之前大 1/3。
我们先随便输出一个汉字,并将其转换成16进制。
// Buffer.From 可以将汉字转换成 16进制
let r = Buffer.from('莫')
console.LOG(r); // <Buffer e8 8e ab>
我们可以发现,结果是 3个字节 长度的 16进制,挨个转换成 2进制。
console.log((0xe8).toString(2)); // 11101000
console.log((0x8e).toString(2)); // 10001110
console.log((0xab).toString(2)); // 10101011
再将得到的 2进制 进行拼接,并转换成 4个字节,并在前面补 0,将其变成 8位 二进制 。然后我们会得到下面的结果。
// 11101000 10001110 10101011
// 00111010 00001000 00111010 00101011
这个结果最大是 001111
,然后我们再将这个结果转换成 十进制。
console.log(parseint('00111010',2)); // 58
console.log(parseInt('00001000',2)); // 8
console.log(parseInt('00111010',2)); // 58
console.log(parseInt('00101011',2)); // 43
这样我们就会得到一个每位都 不大于64 的结果。
根据上面写的对应表,我们就可以推算出这个文字对应的 Base64
编码为 6I6r
,也就是我们上面写的 莫 字。
把这种思路整理一下,我们就可以得到下述代码。
const CHARTS = 'abcDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function transfer(str){
let buf = Buffer.from(str);
let result = '';
for(let b of buf){
result += b.toString(2);
}
return result.match(/(d{6})/g).map(v=>parseInt(v,2)).map(v=>CHARTS[v]).join('');
}
let r = transfer('莫');
console.log(r); // 6I6r
这样就完成了我们的 Base64
的转换。
本篇文章由 莫小尚 创作,文章中如有任何问题和纰漏,欢迎您的指正与交流。 您也可以关注我的 个人站点、博客园 和 掘金,我会在文章产出后同步上传到这些平台上。 最后感谢您的支持!
以上是脚本宝典为你收集整理的学习笔记—编码的发展全部内容,希望文章能够帮你解决学习笔记—编码的发展所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。