网站客服:zx81024163 |

深入解析字符集与字符编码:从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+d8​​00到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() // 
                      

相关阅读:

提醒:请联系我时一定说明是从星空网上看到的!