1. ホーム
  2. javascript

[解決済み] JavaScriptにおける文字列の長さ(バイト数

2022-04-28 14:23:15

質問内容

私のJavaScriptコードでは、次の形式でサーバーにメッセージを構成する必要があります。

<size in bytes>CRLF
<data>CRLF

3
foo

データにはUnicode文字が含まれる場合があります。UTF-8で送信する必要があります。

JavaScriptで文字列の長さをバイト単位で計算するために、最もクロスブラウザに対応した方法を探しています。

ペイロードを構成するために試したことがあります。

return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"

しかし、古いブラウザでは正確な結果が得られません(というか、それらのブラウザの文字列はUTF-16なのでは?)

何か手がかりはありますか?

更新しました。

例:文字列の長さ(バイト) ЭЭХ! Naïve? UTF-8では15バイトですが、ブラウザによっては23バイトと表示されます。

解決方法は?

JavaScriptでネイティブに行う方法はありません。 (参照 リカルド・ガッリ氏の回答 は現代的なアプローチです)。


歴史的な参照やTextEncoderのAPIがあるところでは まだ利用できない .

文字コードがわかっていれば、自分で計算することもできますが。

encodeURIComponent は文字コードとしてUTF-8を仮定しているので、そのエンコーディングが必要であれば、できます。

function lengthInUtf8Bytes(str) {
  // Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
  var m = encodeURIComponent(str).match(/%[89ABab]/g);
  return str.length + (m ? m.length : 0);
}

UTF-8はマルチバイトシーケンスをエンコードする方法なので、これはうまくいくはずです。 エンコードされた最初のバイトは、シングルバイト列の場合は常に上位ビットが0、または16進数の1桁目がC、D、E、Fであるバイトで始まります。 UTF-8でカウントしたいのは、この余分なバイトです。

の表は ウィキペディア を使えば、より明確になります。

Bits        Last code point Byte 1          Byte 2          Byte 3
  7         U+007F          0xxxxxxx
 11         U+07FF          110xxxxx        10xxxxxx
 16         U+FFFF          1110xxxx        10xxxxxx        10xxxxxx
...

その代わりに、ページのエンコーディングを理解する必要がある場合は、このトリックを使用することができます。

function lengthInPageEncoding(s) {
  var a = document.createElement('A');
  a.href = '#' + s;
  var sEncoded = a.href;
  sEncoded = sEncoded.substring(sEncoded.indexOf('#') + 1);
  var m = sEncoded.match(/%[0-9a-f]{2}/g);
  return sEncoded.length - (m ? m.length * 2 : 0);
}