4

文字列と逆方向のバイト数

そこに記述された関数はpack(unpack("string"))、 に屈して適切に動作し"string"ます。"string".getBytes("UTF8")しかし、私はJavaで与えるのと同じ結果を得たいと思っています。

問題は、JavaScript で Java getBytes("UTF8") と同じ機能を提供する関数を作成する方法です。

unpack(str)上記の記事のラテン文字列の場合、奇数の位置をgetBytes("UTF8")追加することを除いて、同じ結果が得られます。0しかし、ラテン語以外の文字列では、まったく異なるように思えます。Java のように JavaScript で文字列データを操作する方法はありますか?

4

4 に答える 4

7

完全な UTF-8 エンコーダーを記述する必要はありません。Unicode 文字列を UTF-8 コード単位を表すバイトの文字列に変換するための、はるかに簡単な JS イディオムがあります。

unescape(encodeURIComponent(str))

(これが機能するのは、escape/でunescape使用される奇妙なエンコーディング%xxが、URI コンポーネントのエスケープで使用される UTF-8 の代わりに、そのコードで ISO-8859-1 文字を表すために 16 進シーケンスを使用するためです。同様decodeURIComponent(escape(bytes))に他の方向にも進みます。)

したがって、配列が必要な場合は次のようになります。

function toUTF8Array(str) {
    var utf8= unescape(encodeURIComponent(str));
    var arr= new Array(utf8.length);
    for (var i= 0; i<utf8.length; i++)
        arr[i]= utf8.charCodeAt(i);
    return arr;
}
于 2013-11-30T17:37:07.900 に答える
3

TextEncoderEncoding Living Standardの一部であり、Chromium ダッシュボードのEncoding APIエントリによると、Firefox で出荷され、Chrome 38 で出荷される予定です。他のブラウザで利用できるテキスト エンコーディングポリフィルもあります。

以下の JavaScript コード サンプルは、Uint8Array期待する値で埋められた を返します。

(new TextEncoder()).encode("string") 
// [115, 116, 114, 105, 110, 103]

inUTF-8 がinstringを に置き換えることを示すより興味深い例îñ:

(new TextEncoder()).encode("strîñg")
[115, 116, 114, 195, 174, 195, 177, 103]
于 2014-09-01T03:55:30.103 に答える
3

この関数を使用できます ( gist ):

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));
        }
        else {
            // let's keep things simple and only handle chars up to U+FFFF...
            utf8.push(0xef, 0xbf, 0xbd); // U+FFFE "replacement character"
        }
    }
    return utf8;
}

使用例:

>>> toUTF8Array("中€")
[228, 184, 173, 226, 130, 172]

Java の byte から int への変換のように、127 を超える値に負の数が必要な場合は、定数を微調整して使用する必要があります。

            utf8.push(0xffffffc0 | (charcode >> 6), 
                      0xffffff80 | (charcode & 0x3f));

            utf8.push(0xffffffe0 | (charcode >> 12), 
                      0xffffff80 | ((charcode>>6) & 0x3f), 
                      0xffffff80 | (charcode & 0x3f));
于 2012-09-21T10:37:24.367 に答える
0

次の関数は、U+FFFF を超えるものを処理します。

JavaScript テキストは UTF-16 であるため、文字列では 2 つの「文字」が使用されて BMP より上の文字を表し、charCodeAt は対応するサロゲート コードを返します。fixedCharCodeAt がこれを処理します。

function encodeTextToUtf8(text) {
    var bin = [];
    for (var i = 0; i < text.length; i++) {
        var v = fixedCharCodeAt(text, i);
        if (v === false) continue;
        encodeCharCodeToUtf8(v, bin);
    }
    return bin;
}

function encodeCharCodeToUtf8(codePt, bin) {
    if (codePt <= 0x7F) {
        bin.push(codePt);
    } else if (codePt <= 0x7FF) {
        bin.push(192 | (codePt >> 6), 128 | (codePt & 63));
    } else if (codePt <= 0xFFFF) {
        bin.push(224 | (codePt >> 12),
            128 | ((codePt >> 6) & 63),
            128 | (codePt & 63));
    } else if (codePt <= 0x1FFFFF) {
        bin.push(240 | (codePt >> 18),
            128 | ((codePt >> 12) & 63), 
            128 | ((codePt >> 6) & 63),
            128 | (codePt & 63));
    }
}

function fixedCharCodeAt (str, idx) {  
    // ex. fixedCharCodeAt ('\uD800\uDC00', 0); // 65536  
    // ex. fixedCharCodeAt ('\uD800\uDC00', 1); // 65536  
    idx = idx || 0;  
    var code = str.charCodeAt(idx);  
    var hi, low;  
    if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)  
        hi = code;  
        low = str.charCodeAt(idx+1);  
        if (isNaN(low)) {  
            throw(encoding_error.invalid_surrogate_pair.replace('%pos%', idx));
        }  
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;  
    }  
    if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate  
        // We return false to allow loops to skip this iteration since should have already handled high surrogate above in the previous iteration  
        return false;  
        /*hi = str.charCodeAt(idx-1); 
          low = code; 
          return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;*/  
    }  
    return code;  
}  
于 2013-01-22T08:35:31.910 に答える