gpt4 book ai didi

javascript - UTF-8 编码算法如何在 8 位 block 上工作(在 JavaScript 中)?

转载 作者:行者123 更新时间:2023-12-02 22:14:22 25 4
gpt4 key购买 nike

我正在看this :

function encodeCodePoint(codePoint) {
if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
return stringFromCharCode(codePoint);
}
var symbol = '';
if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
}
else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
checkScalarValue(codePoint);
symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
symbol += createByte(codePoint, 6);
}
else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
symbol += createByte(codePoint, 12);
symbol += createByte(codePoint, 6);
}
symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
return symbol;
}

在 JavaScript 中,它似乎利用了 JavaScript 中的数字(我认为)大约 32 位长这一事实。因此它会进行一些我不熟悉的位操作并获取编码值。与decode函数相同:

function decodeSymbol() {
var byte1;
var byte2;
var byte3;
var byte4;
var codePoint;

if (byteIndex > byteCount) {
throw Error('Invalid byte index');
}

if (byteIndex == byteCount) {
return false;
}

// Read first byte
byte1 = byteArray[byteIndex] & 0xFF;
byteIndex++;

// 1-byte sequence (no continuation bytes)
if ((byte1 & 0x80) == 0) {
return byte1;
}

// 2-byte sequence
if ((byte1 & 0xE0) == 0xC0) {
byte2 = readContinuationByte();
codePoint = ((byte1 & 0x1F) << 6) | byte2;
if (codePoint >= 0x80) {
return codePoint;
} else {
throw Error('Invalid continuation byte');
}
}

// 3-byte sequence (may include unpaired surrogates)
if ((byte1 & 0xF0) == 0xE0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
if (codePoint >= 0x0800) {
checkScalarValue(codePoint);
return codePoint;
} else {
throw Error('Invalid continuation byte');
}
}

// 4-byte sequence
if ((byte1 & 0xF8) == 0xF0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
byte4 = readContinuationByte();
codePoint = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0C) |
(byte3 << 0x06) | byte4;
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
return codePoint;
}
}

throw Error('Invalid UTF-8 detected');
}

基本上,我无法完全阅读这段代码,也无法真正判断发生了什么。想知 Prop 有更好的位操作能力或 UTF-8 编码知识的人是否可以在较高层次上描述编码和解码的输入和输出,以及非常粗略地描述它是如何从输入到输出的每个。我正在尝试构建一个 utf-8 编码器/解码器,但没有确切地了解如何将 8 位流分块为 1 到 4 字节 block ,部分原因是 JavaScript 32 位整数问题妨碍了我的思考。但对我来说,发生的事情似乎是这样的:

解码:

  • 我们有一个 8 位(1 字节)数据流。
  • 我们得到一个字节
  • 我们检查该字节是否在某种特定范围内(我不知道)
  • 如果它在某个范围内,那么我们就知道后面有一个额外的字节,或类似的东西。
  • 然后我们收集该 Angular 色的所有字节...
  • 对于 JavaScript,将其转换为整数,然后进行 String.fromCharCode(integer) 之类的转换。

我缺少的是它到底是如何从 1 字节序列变为最多 4 字节的,它是如何完成该部分的?

编码:

  • 这取决于语言/架构,因为某些架构的整数为 16、32 或 64 位(...我猜...)。
  • 对于 JavaScript,采用 32 位整数并执行一些位操作魔术来提取该字符的 1 到 4 个字节。它怎么知道要接收多少字节???
  • 重复此操作,直到获得字节数组。

想知道是否有人可以填补我理解上的空白。我并不是在寻找每一个位操作步骤,因为有很多。我只是在寻找我在上面的分析中强调的问题。

最佳答案

JS 整数具有 32 位二进制运算符,因此您可以安全地在一个数字中使用 4 x 8 位(4 字节)。这就是您的解码器作为参数接收的内容。

<小时/>

UTF-8 编码的大小是可变的。如果代码点只需要 7 位 (= ASCII),那么它将适合一个字节,该字节有一个前导零以表明它只有一个字节:

  0XXXXXXXX

现在要检查代码点是否只有一个字节,可以检查高字节中的某处是否设置了一位。这可以通过将代码点与 0xFFFFF80 进行比较来完成,后者设置了除最后 8 之外的所有位。因此,如果按位和结果不等于 0,则在高字节中的某个位置设置了一个位.

  1111111111111111111110000000 &
0XXXXXXX
= 0
<小时/>

现在,如果超过 7 位,第一个字节包含字节数,后面的所有字节都在开头包含 01 序列,对于 4 个字节来说,这将是:

  11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

例如,现在要获取高 8 个编码位,可以右移 18:

  1110XXX 10XXXXX

关于javascript - UTF-8 编码算法如何在 8 位 block 上工作(在 JavaScript 中)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59442779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com