深入解析字符集与字符编码:从ASCII到Unicode,前端开发中的关键知识
2025-02-27 22:02:28发布 浏览344次 信息编号:217505
友情提醒:凡是以各种理由向你收取费用,均有骗子嫌疑,请提高警惕,不要轻易支付。
深入解析字符集与字符编码:从ASCII到Unicode,前端开发中的关键知识
字符集和字符编码
字符集是字符的集合,例如常见的ASCII字符集,字符集,字符集等。这些不同的字符集之间的最大区别是所包含的字符数的差异。
字符编码代表字符集的实际编码规则,用于计算机解析字符,例如GBK,UTF-8等。字符编码的本质是如何使用二进制字节来表示字符的问题。
角色集和编码是一种一对多的关系。同一字符集中可能有多个字符编码,例如字符集包括UTF-8,UTF-16,等。
在前端开发中,程序使用字符集,源文本通常基于UTF-8编码。
但是,JS代码中的字符串类型是UTF-16编码,这就是为什么您遇到前端中出现的API接口返回的字符串,因为大多数服务都使用UTF-8编码,并且前端编码方法不一致。
说到角色集的发展历史,可以用一个句子进行总结:几乎所有都是ASCII角色集的扩展。
ASCII
我们知道计算机使用二进制处理信息。
其中,每个二进制位具有两个状态:0和1。一个字节具有8个二进制位,可以有256个州。
ASCII是基于拉丁字母的单字节字符集,主要用于显示英语。它的编码和字符逐一对应,因为它在一个字节中使用8个二进制位来表示它,并且不会超过256个字符。
标准的ASCII字符总共有128个字符(2^7),其中32个控制字符是第一个和96个可打印字符,包括常用的字母数字标点符号等。
'a'.charCodeAt() // 97
'A'.charCodeAt() // 65
'9'.charCodeAt() // 57
'.'.charCodeAt() // 46
如上所述,每个字符将对应于一个编码(使用数值识别),并且总计为0-128。完整的ASCII代码表,易于在线查找。
通过ASCII代码表,我们发现小写字母在大写字母旁边没有排序?这是为了促进案例之间的转换,A排名65(64 + 1),A排名为97(64 + 32 + 1)。
65 ^ 32 = 97
// A ^ 32 = a
角色集发展的历史
ASCII几乎是所有角色集的基础。
标准ASCII代码只能标记多达128个字符。欧美国家可以很好地使用它,但是在其他国家,自然没有足够的角色。
目前,最高位开始被记住。通过扩展ASCII代码的最高位,它还可以满足某些用于特殊符号的国家 /地区的需求。这是为了扩展ASCII代码。
但是亚洲,具有数千个角色的非洲和拉丁国家只能以新的方式使用。
例如,在中文中,它再次扩展。小于127的字符的含义与标准ASCII代码的含义相同。当有必要识别汉字时,使用了2个字节,每个字节大于127。此多字节字符集,即由于连续扩展,例如传统字符和各种符号,甚至是少数族裔语言符号,使用了包括GBK在内的不同字符集。
因此,许多国家已经制定了自己的编码角色集,这些角色集基本上基于ASCII。
尽管每个字符集都与标准ASCII代码兼容,但使用通信的不便是显而易见的,并且乱码代码也无处不在。为了解决这个相互战斗的问题,角色集诞生了。
这是国际组织开发的角色集计划,以存储世界上所有的文本和符号。
前128个字符与ASCII相同。扩展后,数量0-用于映射这些字符,并且可以最多有一个字符。仍然只使用其中一小部分。
通常,两个字节用于表示字符。
每个代码点对应于一个字符,最常见的字符位于正面的65,536个字符,范围为U+0000到U+FFFF。
一般汉字的代码点间隔为u+2e80 -U+9fff。
编码方法
代码
编码后的字节数
UTF-8
8
1-4字节
UTF-16
16
2个字节或4个字节
UTF-32
32位
4个字节
此外,为什么您总是看到用于表示各种数据(例如代码点)的十六进制数据?
因为两个数字的十六进制完全等于一个字节8位0xff =。
UTF-8
UTF-8是一种可变长度的字符编码方法。当前,使用1到4个字节来编码字符。它是时代使用最广泛的编码方法,前端的联系最多。
应该注意的是,汉字通常占3个字节,表情符号通常为4个字节。
UTF-8编码规则:
字节数
代码点数
代码点范围
编码方法
U+0000〜U+007F
0×××××
11
U+0080〜U+07ff
110×××10××××××
16
U+0800〜U+FFFF
1110×××× 10××××× 10××××××
21
U+10000〜U+
11110××10×××10××××10×××10×××××××××××××××××××××
通过上表的编码规则,我们可以执行各种转换。
下面,我们以中文角色的编码转换为例,例如中文角色“好”:
'好'代码点:'good'。()\\ 22909,结果为22909;
22909 UTF-8中的编码间隔U+0800(2048)为U+FFFF(65535);
二进制值为22909:1101,有15位;
3个字节的编码需要16位,第一个位是0,并且根据表中的规则将其分为3组:0101;
填写相应的前缀:10序列以获得3个字节;
将获得的三个字节转换为十六进制数据:E5 A5 BD,因此具有汉字“ good”的UTF-8 IS是:E5 A5 BD。
我们用于验证 - 功能支持中文编码的UTF -8:
encodeURI('好') // '%E5%A5%BD'
删除百分比,结果完全相同。
UTF-16
UTF-16编码方法:基本平面中的字符占据2个字节(U+0000到U+FFFF),而辅助平面中的字符占据了4个字节(u+to u+to u+)。
也就是说,UTF-16的编码长度是2个字节或4个字节。当两个字节时,它实际上与。
而且还有一个原则,即在基本的多语言平面中,从u+d800到u+dfff的代码点间隔与字符不符。 UTF-16需要使用此代码位来编码辅助平面中的字符。
它的具体规则:
请参阅以下示例:
中文字符“好”,“良好”。()// 22909,代码点小于u+ffff,直接转换十六进制:579d。 emoji'','。()//,代码点需要拆分:低:Math.floor((((( - 65536) / 1024) / 1024))) + // 55357,获取D83D高:(( - ) + //
使用。方法:
String.fromCharCode(0xD83D, 0xDE04) // ''
应该清楚的是,其中的字符串基于UTF-16编码的大型字节。
UTF-32是一个固定的编码,每个代码位均使用四个字节编码。优点是它对应于一对一,但缺点是它太浪费了空间。
比较
以下将选择字母,汉字和表情符号字符来编码比较和观看:
// UTF-8
'a': 97 - 0x61
'好': 22909 - (0xE5 0xA5 0xBD)
'': 128516 - (0xF0 0x9F 0x98 0x84)
// UTF-16
'a': 97 - 0x0061
'好': 22909 - 0x597d
'': 128516 - (0xD83D, 0xDE04)
如您所见,UTF-8是可变长度的1-4字节,符号为8位; UTF-16为2或4个字节,符号为16位。
记住这里的UTF-16符号对我们了解以下问题有帮助。
在前端开发中进行编码
如前所述,其字符串基于UTF-16编码,因此在计算字符串的长度时,我们需要先了解UTF-16编码。
下面,让我们看一下处理字符串时可能遇到的问题。
字符串长度计算
字符串的属性实际上是使用UTF-16中的符号数来计算的:
因此,当特定字符中有2个符号时,即使显示一个字符,也等于2。
'a'.length // 1
'好'.length // 1,多数汉字都是基本字符平面,只有一个码元,长度就为1。
''.length // 2
组合字符的长度
字符也有特殊的组合,通常是指某些带有标点符号的字符:é。
'é'.length // 2
'e\u0301'.length // 2
// 获取码点时,忽略了标点符号,显示的是字母的码点
'é'.codePointAt() // 101
'e'.codePointAt() // 101
要正常组合字符,请使用()。
'é'.normalize().length = 1。
多代码字符操作
当使用下标获得多代码字符的值时,您得到的将是其代码字:
''[0] // '\uD83D'
''[1] // '\uDE04'
'123'[0] // '1'
循环时,使用将弄脏代码,而for for for for for正常:
let smile = ''
for(let i = 0; i < smile.length; i++) {
console.log(smile[i])
}
// �
// �
for (let tt of smile) {
console.log(tt)
}
//
但是,可以使用转换为扩展数组的方法访问它:
[...''][0] // ''
Array.from('') // ['']
您还可以使用代码点:
String.fromCodePoint(''.codePointAt()) // ''
对于此特殊字符,将使用以下字符串方法将符号分开:
split(),slice(),(),(),(),(),(),()。
''.slice(0, 2) // ''
''.slice(0, 1) // '\uD83D'
''.slice(1, 2) // '\uDE04'
''.substr(0,1) // '\uD83D'
''.substr(0,2) // ''
''.split('') // ['\uD83D', '\uDE04']
U常规修饰符
ES6将AU修饰符添加到规律性中,以正确处理大于\ uffff的字符,这意味着它可以正确处理四个字节的UTF-16编码。
/^\S$/.test('') // false
/^\S$/u.test('') // true
但是对于组合字符,U修饰符不起作用:
/^\S$/u.test('é') // false
/^\S$/u.test('e\u0301') // false
逃脱角色
我们还需要注意,逃脱字符的计算将基于实际字符:
'\x3f'.length // 1
'?'.length // 1
它也可以在阅读操作过程中正常处理:
'\x3f'[0] // '?'
'\x3f'.split('') // ['?']
常见的API
处理编码时,前端提供了一些可以使用的API,这将促进我们在实际工作中处理此问题。
过程代码点和字符
'a'.charAt() // 'a'
''.charAt() // '\uD83D'
''.charAt(1) // '\uDE04'
// 小于 U+FFFF
'好'.codePointAt() // 22909
'好'.charCodeAt() // 22909
// 大于 U+FFFF
''.charCodeAt() // 55357
''.charCodeAt(1) // 56836
''.codePointAt() // 128516
''.codePointAt(1) // 56836
String.fromCharCode(55357, 56836, 123) // '{'
String.fromCodePoint(128516, 123, 8776) // '{≈'
,使用UTF-8编码将代码点流转换为字节流。
:解码。
默认的编码方法是UTF-8,它可以解决字符对UTF-8编码的问题。
const txtEn = new TextEncoder()
const enVal = txtEn.encode('好')
// Uint8Array(3) [229, 165, 189]
const txtDe = new TextDecoder()
txtDe.decode(enVal) // '好'
IE不支持它。
..()
对于语调符号和口音符号,提供了两种方法,一种是直接提供符号字符,例如é(代码点233);另一个是结合字符,例如上面提到的é(代码点101)。
对于具有不同代码点但本质上相同的字符,无法识别它们:
'é' === 'é' // false
()方法的引入是解决此问题。它将以某种方式将不同字符的不同表示方法统一为标准形式:
'é' === 'é'.normalize() //
相关阅读:
提醒:请联系我时一定说明是从星空网上看到的!