58

この.charCodeAt関数は、文字の Unicode コードを返します。しかし、代わりにバイト配列を取得したいと思います。charcode が 127 を超える場合、文字は 2 バイト以上で格納されます。

var arr=[];
for(var i=0; i<str.length; i++) {
    arr.push(str.charCodeAt(i))
}
4

9 に答える 9

78

UTF-8 で Unicode をエンコードするロジックは、基本的に次のとおりです。

  • 1 文字あたり 4 バイトまで使用できます。可能な限り少ないバイト数が使用されます。
  • U+007F までの文字は、1 バイトでエンコードされます。
  • マルチバイト シーケンスの場合、最初のバイトの先頭の 1 ビットの数は、文字のバイト数を示します。最初のバイトの残りのビットは、文字のビットをエンコードするために使用できます。
  • 継続バイトは 10 で始まり、残りの 6 ビットは文字のビットをエンコードします。

これは、JavaScript UTF-16 文字列を UTF-8 でエンコードするために、しばらく前に書いた関数です。

function toUTF8Array(str) {
    var utf8 = [];
    for (var i=0; i < str.length; i++) {
        var charcode = str.charCodeAt(i);
        if (charcode < 0x80) utf8.push(charcode);
        else if (charcode < 0x800) {
            utf8.push(0xc0 | (charcode >> 6), 
                      0x80 | (charcode & 0x3f));
        }
        else if (charcode < 0xd800 || charcode >= 0xe000) {
            utf8.push(0xe0 | (charcode >> 12), 
                      0x80 | ((charcode>>6) & 0x3f), 
                      0x80 | (charcode & 0x3f));
        }
        // surrogate pair
        else {
            i++;
            // UTF-16 encodes 0x10000-0x10FFFF by
            // subtracting 0x10000 and splitting the
            // 20 bits of 0x0-0xFFFFF into two halves
            charcode = 0x10000 + (((charcode & 0x3ff)<<10)
                      | (str.charCodeAt(i) & 0x3ff));
            utf8.push(0xf0 | (charcode >>18), 
                      0x80 | ((charcode>>12) & 0x3f), 
                      0x80 | ((charcode>>6) & 0x3f), 
                      0x80 | (charcode & 0x3f));
        }
    }
    return utf8;
}
于 2013-09-10T22:43:30.343 に答える
11

Google Closure ライブラリには、UTF-8 およびバイト配列との間で変換する関数があります。ライブラリ全体を使用したくない場合は、ここから関数をコピーできます。完全を期すために、文字列を UTF-8 バイト配列に変換するコードは次のとおりです。

goog.crypt.stringToUtf8ByteArray = function(str) {
  // TODO(user): Use native implementations if/when available
  var out = [], p = 0;
  for (var i = 0; i < str.length; i++) {
    var c = str.charCodeAt(i);
    if (c < 128) {
      out[p++] = c;
    } else if (c < 2048) {
      out[p++] = (c >> 6) | 192;
      out[p++] = (c & 63) | 128;
    } else if (
        ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&
        ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
      // Surrogate Pair
      c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
      out[p++] = (c >> 18) | 240;
      out[p++] = ((c >> 12) & 63) | 128;
      out[p++] = ((c >> 6) & 63) | 128;
      out[p++] = (c & 63) | 128;
    } else {
      out[p++] = (c >> 12) | 224;
      out[p++] = ((c >> 6) & 63) | 128;
      out[p++] = (c & 63) | 128;
    }
  }
  return out;
};
于 2015-01-30T01:05:29.953 に答える
1

私はジョニのソリューションを使用していましたが、うまくいきましたが、これははるかに短くなっています。

これは、 Mozilla の Base64 Unicode ディスカッションのソリューション #3 の atobUTF16() 関数に触発されました。

function convertStringToUTF8ByteArray(str) {
    let binaryArray = new Uint8Array(str.length)
    Array.prototype.forEach.call(binaryArray, function (el, idx, arr) { arr[idx] = str.charCodeAt(idx) })
    return binaryArray
}
于 2019-05-31T22:59:45.590 に答える