转换UTF-8字符串,每个字符只有8位

时间:2016-06-16 19:19:45

标签: javascript string utf-8

我有一个JavaScript字符串,其中包含charCode大于 255 的字符。

我希望能够将该字符串编码/解码为另一个字符串,其所有charCode小于或等于255。

对字符没有限制(例如:可以是不可打印的)。

我想要一个尽可能快的解决方案,并尽可能地生成一个字符串。

它也适用于任何UTF-8角色。

我发现encodeURI确实如此,但似乎需要很大的空间。

encodeURI('ĉ') === "%C4%89" // 6 bytes...

有什么比encodeURI更好吗?

3 个答案:

答案 0 :(得分:2)

您要做的是将字符串编码为UTF8。谷歌搜索如何在Javascript中执行此操作,我找到了http://monsur.hossa.in/2012/07/20/utf-8-in-javascript.html,它给出了:

function encode_utf8( s ) {
  return unescape( encodeURIComponent( s ) );
}

function decode_utf8( s ) {
  return decodeURIComponent( escape( s ) );
}

或者简而言之,几乎就是你已经找到的东西,再加上你没有想到的'%xx'代码到一个字节。

答案 1 :(得分:1)

您可以使用.charCodeAt(position)获取字符的ASCII值。您可以使用此字符将字符拆分为多个字符。

首先,通过循环字符串获取每个字符的字符代码。创建一个临时的空字符串,当char代码高于当前字符的255时,从中除以255,并放置ÿ(扩展ASCII表的第256个字符),然后一旦它低于255使用String.fromCharCode(charCode),将其转换为字符,并将其放在临时字符串的末尾,最后用该字符串替换该字符。

function encode(string) {
    var result = [];
    for (var i = 0; i < string.length; i++) {
    var charCode = string.charCodeAt(i);
        var temp = "";
        while (charCode > 255) {
            temp += "ÿ";
            charCode -= 255;
        }
        result.push(temp + String.fromCharCode(charCode));
    }
    return result.join(",");
}

上面的编码器在每个组后面都有一个逗号,这可能会导致解码时出现问题,因此我们需要使用,(?!,)正则表达式来匹配多个逗号中的最后一个逗号。

function decode(string) {
    var characters = string.split(/,(?!,)/g);
    var result = "";
    for (var i = 0; i < characters.length; i++) {
        var charCode = 0;
        for (var j = 0; j < characters[i].length; j++) {
            charCode += characters[i].charCodeAt(j);
        }
        result += String.fromCharCode(charCode);
    }
    return result;
}

答案 2 :(得分:1)

UTF-8已经是unicode文本的编码,每个字符使用8位。您只需通过线路发送UTF-8字符串即可。

通常,JavaScript字符串由UTF-16字符组成。

对于此类字符串,您可以将每个UTF-16字符编码为两个8位字符,也可以使用动态长度编码,如UTF-8。

如果您有许多非ASCII字符,第一个可能会产生较小的结果。

&#13;
&#13;
// See http://monsur.hossa.in/2012/07/20/utf-8-in-javascript.html
function encode_utf8(s) {
  return unescape(encodeURIComponent(s));
}

function decode_utf8(s) {
  return decodeURIComponent(escape(s));
}

function encode_fixed_length(s) {
  let length = s.length << 1,
      bytes = new Array(length);
  for (let i = 0; i < length; ++i) {
    let code = s.charCodeAt(i >> 1);
    bytes[i] = code >> 8;
    bytes[++i] = code & 0xFF;
  }
  return String.fromCharCode.apply(undefined, bytes);
}

function decode_fixed_length(s) {
  let length = s.length,
      chars = new Array(length >> 1);
  for (let i = 0; i < length; ++i) {
    chars[i >> 1] = (s.charCodeAt(i) << 8) + s.charCodeAt(++i);
  }
  return String.fromCharCode.apply(undefined, chars);
}

string_1 = "\u0000\u000F\u00FF";
string_2 = "\u00FF\u0FFF\uFFFF";

console.log(encode_fixed_length(string_1)); // "\x00\x00\x00\x0F\x00\xFF"
console.log(encode_fixed_length(string_2)); // "\x00\xFF\x0F\xFF\xFF\xFF"

console.log(encode_utf8(string_1));         // "\x00\x0F\xC3\xBF" 
console.log(encode_utf8(string_2));         // "\xC3\xBF\xE0\xBF\xBF\xEF\xBF\xBF"
&#13;
&#13;
&#13;

效果比较:请参阅https://jsfiddle.net/r0d9pm25/1/

Firefox 47中500000次迭代的结果:

  • 6159.91ms encode_fixed_length()
  • 7177.35ms encode_utf8()