(类似的问题已在StackOverflow上提出,但不完全是这样。最近的可能是“javascript how to convert unicode string to ascii”,其中已有评论“这必须是dup [licate]“。我已经阅读了一些类似的帖子,但他们没有回答我的具体问题。我看过非常好的W3Schools网站,并且还用Google搜索它,但也没有找到答案。因此,非常感谢这里的任何提示。)
我将一个字节数组传递给一段JavaScript。在JavaScript中,数据以字符串形式到达。我不知道传输机制,因为它来自第三方应用程序。我甚至不知道字符串是“宽”还是“窄”。
在我的JavaScript中,我有一些代码,如b = str.charCodeAt(pos);
。
我的问题是像字符0x2020 = 8224这样的字节值如0x86 = 134。这似乎是因为我的原始字节被解释为Latin-1(可能)'匕首'字符,然后是转换为等效的Unicode代码点。 (问题可能是也可能不是JavaScript的'错误'。)其他值也会出现类似的问题,尽管范围0x00..0x7F和0xA0..0xFF看起来很好,但大多数值来自0x80..0x9F受到影响,每种情况下,该值似乎是原始Latin-1的Unicode。
另一个观察结果是,如果以字节为单位测量长度,则字符串的长度是我对窄字符串的期望。 (另一方面,如果length返回抽象字符中的值,则不会告诉我任何事情。)
因此,在JavaScript中,有没有办法获取字符串中的“原始”字节,或者直接获取Latin-1或ASCII字符代码,或者在字符编码之间进行转换,或者定义默认值编码吗
我可以编写自己的映射,但我不愿意。我希望这就是我最终会做的事情,但这种感觉会让人觉得有什么污点。
我也在研究是否可以在调用应用程序中调整任何内容(因为它可能将数据作为宽字符串传递,但我对此表示怀疑)。
无论哪种方式,我都会对是否有一个简单的JavaScript解决方案感兴趣,或者了解为什么没有。
(如果传入的数据是字符数据,那么自动处理Unicode就会很棒。但事实并非如此,它只是一个二进制数据流。)
感谢。
答案 0 :(得分:6)
String中没有原始字节。 EcmaScript规范将字符串定义为UTF-16代码单元序列。这是任何翻译人员遇到的最细粒度的表示。
在浏览器上没有编码库。如果您尝试将字节数组表示为字符串并想要重新编码,则必须自行滚动。
如果您的字符串恰好是有效的ASCII,那么您可以使用charCodeAt
方法获取代码单元的数值。
"\n".charCodeAt(0) === 10
答案 1 :(得分:3)
从Javascript(Ecmascript)规范开始:http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf。说:
8.4字符串类型 String类型是所有有限有序的集合 零个或多个16位无符号整数的序列 值(“元素”)。字符串类型通常是 用于表示正在运行的ECMAScript中的文本数据 程序,在这种情况下,String中的每个元素都是 作为代码单元值处理(见第6章)。每 元素被视为占据一个位置 序列。这些职位编入索引 非负整数。第一个元素(如果有的话)是 在位置0,位置的下一个元素(如果有的话) 1,依此类推。 String的长度是数字 其中的元素(即16位值)。该 empty String的长度为零,因此包含 没有元素。
当String包含实际的文本数据时 element被认为是单个UTF-16代码单元。 这是否是一个实际的存储格式 字符串,String中的字符编号为 他们的初始代码单元元素位置就像它们一样 用UTF-16表示。对字符串的所有操作 (除非另有说明)将它们视为序列 未分化的16位无符号整数;他们不 确保生成的String是标准化形式,也不是 他们确保语言敏感的结果。
注意这个设计背后的基本原理是保持 Strings的实现简单而高效 尽可能。意图是文本数据进入 来自外部的执行环境(例如,用户输入, 从文件读取或通过网络接收的文本等) 在转换为Unicode标准化表单C之前 运行程序看到它。通常这会发生在 同一时间传入的文本从其原始文本转换 字符编码为Unicode(并且不会强加额外的 高架)。因为建议使用ECMAScript源码 代码采用标准化形式C,保证字符串文字 标准化(如果源文本保证是 normalized),只要它们不包含任何Unicode 逃逸序列。
charCodeAt(
p )
给出的是索引 p 中字符的UTF-16值(16位数)在字符串中。由于UTF-16直接表示Unicode的基本多语言平面(即代码点U+0000
- U+D7FF
和U+E000
- U+FFFF
,因此您的Latin-1字符应为您的值期待他们。
事实上他们并没有告诉我你的入站第3个八位字节流有编码问题 - 如果转换为UTF-16并且输入的入站八位字节流编码错误,你会得到奇怪的结果。
也许它被视为vanilla ASCII,实际上它是UTF-8(反之亦然)。 UTF-8表示高于0x7F的代码点为2字节,3字节或4字节的“有向图”。