Javascript:基于BYTE的十六进制转义序列的unicode字符(不是代理)

时间:2015-08-01 12:44:13

标签: javascript unicode utf-8 hex utf-16

在javascript中我试图将unicode转换为与C兼容的基于字节的十六进制转义序列:

即。

成为:\xF0\x9F\x98\x84(正确)

不是javascript代理,而不是\uD83D\uDE04(错误)

我无法弄清楚C想要的四个字节与javascript使用的两个代理之间的数学关系。我怀疑算法比我的微弱尝试复杂得多。

感谢您的任何提示。

3 个答案:

答案 0 :(得分:1)

您的C代码需要一个UTF-8字符串(该符号表示为4个字节)。您看到的JS表示是UTF-16但是(符号表示为2 uint16 s,代理对)。
首先需要为符号(来自UTF-16 JS字符串)获取(Unicode)代码点,然后从中为它构建UTF-8表示。

从ES6开始,您可以使用codePointAt method作为第一部分,即使不支持,我也建议将其用作垫片。我想你不想自己解码代理对:-)
对于其他人,我不认为这是一种图书馆方法,但您可以自己编写according到规范:

function hex(x) {
    x = x.toString(16);
    return (x.length > 2 ? "\\u0000" : "\\x00").slice(0,-x.length)+x.toUpperCase();
}
var c = "";
console.log(c.length, hex(c.charCodeAt(0))+hex(c.charCodeAt(1))); // 2, "\uD83D\uDE04"
var cp = c.codePointAt(0);
var bytes = new Uint8Array(4);
bytes[3] = 0x80 | cp & 0x3F;
bytes[2] = 0x80 | (cp >>>= 6) & 0x3F;
bytes[1] = 0x80 | (cp >>>= 6) & 0x3F;
bytes[0] = 0xF0 | (cp >>>= 6) & 0x3F;
console.log(Array.prototype.map.call(bytes, hex).join("")) // "\xf0\x9f\x98\x84"

(在Chrome中测试)

答案 1 :(得分:1)

在此处找到解决方案:http://jonisalonen.com/2012/from-utf-16-to-utf-8-in-javascript/

我从未想过那个数学,哇。

有点缩小

parentsSeq +: Seq(parent)

答案 2 :(得分:1)

docs这样做有效:

var input = "\uD83D\uDE04";
var result = encodeURIComponent(input).replace(/%/g, "\\x"); // \xF0\x9F\x98\x84

更新:实际上,C字符串可以包含数字和字母而不会转义,但是如果你真的需要转义它们:

function escape(s, escapeEverything) {
    if (escapeEverything) {
        s = s.replace(/[\x10-\x7f]/g, function (s) {
            return "-x" + s.charCodeAt(0).toString(16).toUpperCase();
        });
    }
    s = encodeURIComponent(s).replace(/%/g, "\\x");
    if (escapeEverything) {
        s = s.replace(/\-/g, "\\");
    }
    return s;
}