JavaScript替代Ruby的force_encoding(Encoding::ASCII_8BIT)

问题描述 投票:0回答:1

我正在阅读《构建Git》这本书,但试图用JavaScript构建我的实现。在读取这种显然只有Ruby才会使用的文件格式的数据的部分,我陷入了困境。下面是书中关于这方面的节选。

请注意,我们将字符串的编码13设置为ASCII_8BIT,这是Ruby表示字符串代表任意二进制数据而不是文本本身的方式。虽然我们要存储的 blobs 都是 ASCII 兼容的源代码,但 Git 允许 blobs 可以是任何类型的文件,当然其他类型的对象,尤其是树,也会包含非文本数据。这样设置编码意味着当字符串与其他字符串进行连接时,我们不会出现令人惊讶的错误;Ruby看到它是二进制数据,只是将字节进行连接,而不会尝试进行任何字符转换。

有没有办法在JS中模拟这种编码?

或者

有没有其他的编码,我可以使用JS和Ruby共享的编码,而不会破坏任何东西?

此外,我还尝试过使用 Buffer.from(< text input >, 'binary') 但它所产生的字节数与ruby的 ASCII-8BIT 返回,因为在Node.js中 binary 中映射为 ISO-8859-1.

ruby
1个回答
3
投票

Node当然支持二进制数据,这也是某种程度上的。Buffer 是为了。然而,关键是要知道你要把什么转换为什么。例如,表情符号 "☺️" 是以UTF-8编码的六个字节。

// UTF-16 (JS) string to UTF-8 representation
Buffer.from('☺️', 'utf-8')
// => <Buffer e2 98 ba ef b8 8f>

如果你碰巧有一个不是本地JS字符串的字符串(即它的编码是不同的),你可以使用编码参数来制作 Buffer 以不同的方式解释每个字符(虽然只支持几种不同的转换)。例如,如果我们有一串6个字符,对应上面的6个数字,那么对于JavaScript来说,它不是笑脸,而是 Buffer.from 可以帮助我们重新包装它。

Buffer.from('\u00e2\u0098\u00ba\u00ef\u00b8\u008f', 'binary')
// => <Buffer e2 98 ba ef b8 8f>

JavaScript本身的字符串只有一种编码,因此,参数的 'binary' 并不是真正的二进制编码,而是一种操作模式,用于对 Buffer.from,告诉它这个字符串 本来 二进制字符串 如果 每一个字符都是一个字节(然而,由于JavaScript内部使用UCS-2,每个字符总是用两个字节来表示)。因此,如果你在U+0000到U+00FF的范围内使用它,它将不会做正确的事情,因为没有这样的事情(GIGO原则). 它实际上要做的是获取每个字符的低字节,这可能不是你想要的。

Buffer.from('STUFF', 'binary')    // 8BIT range: U+0000 to U+00FF
// => <Buffer 42 59 54 45 53> ("STUFF")

Buffer.from('STUFF', 'binary')  // U+FF33 U+FF34 U+FF35 U+FF26 U+FF26
// => <Buffer 33 34 35 26 26> (garbage)

所以,Node的 Buffer 架构 完全对应于Ruby的 ASCII-8BIT "编码" (二进制是一种编码,就像 "秃头 "是一种发型一样--它只是意味着没有任何解释附加在字节上,例如在ASCII中,65表示 "A";但在二进制 "编码 "中,65只是65)。Buffer.from'binary' 让你把一个字符对应一个字节的奇怪字符串转换成一个。Buffer. 它不是处理二进制数据的正常方式,它的功能是当二进制数据被错误地读成字符串时,解除二进制数据的混乱。

我假设你是把一个文件读成字符串,然后试图把它转换成一个 Buffer - 但您的字符串实际上并不是 Node 认为的 "二进制 "形式(从 U+0000 到 U+00FF 的字符序列,因此 "在 Node.js 中" 。binary 中映射为 ISO-8859-1"其实并不正确,因为ISO-8859-1是一个从0x00到0xFF范围内的字符序列--一个单字节编码!)。)

理想情况下,如果要用二进制表示文件内容,你会希望读取文件的 作为 Buffer 首先(通过使用 fs.readFile 没有编码),而没有接触过一个字符串。

如果我的猜测不正确,请说明你的 < text input > 是,以及你如何获得它,在这种情况下,"它不会导致相同数量的字节")。)

EDIT: 我似乎喜欢打 Array.from 太多了 这就是 Buffer.from当然了

© www.soinside.com 2019 - 2024. All rights reserved.