4

unsafe土地へようこそ。

私は、ASCIIまたはUTF-16のいずれかである可能性のある長さ不明の管理されていないバイトバッファの形式で、0で終了するCスタイルの文字列を提供するレガシーライブラリに対してP/Invokeを実行していますが、その兆候はまったくありません-バイトストリーム自体以外は...

String現在、マネージドfromChar*またはを作成する必要があるかどうかを判断するために、シングルおよびダブル 0 バイトのチェックに基づく悪いスキームがありますSByte*。このスキームは、 より高いすべての Unicode コードポイントで明らかに崩壊しますU+00FF

これは私が持っているものです:

  • アンマネージド バイト バッファーのアドレス。
  • アンマネージ バイト バッファの長さは不明です。
  • アンマネージ バイト バッファーは、0 で終わる ASCII C スタイル文字列または 0 で終わる UTF-16 C スタイル文字列のいずれかです。

これは私が欲しいものです:

  • StringASCII か UTF-16 かを問わず、アンマネージ バイト バッファから正しいマネージを作成します。

その問題は一般的に解決可能ですか?

4

3 に答える 3

4

100%解決できるとは思えません。バッファーに 6c 34 00 00 ("l4") が含まれている場合、それは水を表す中国語の記号ですか、それとも単に ASCII の下位の L と 4 ですか? ただし、特定の文字列によっては、「ほとんどの場合」正しく推測できるはずです。

UTF-16 はリトル エンディアンですか、それとも (おそらく) ビッグ エンディアンですか?

最大のリスクはバッファ オーバーランです。たとえば、バッファーが 00 で始まる場合、それは長さゼロの ASCII 文字列ですか、それとも UTF-16BE として解釈するバッファーをさらに準備する必要がありますか?

于 2010-07-01T09:16:34.220 に答える
2

その問題は一般的に解決可能ですか?

いいえ。

文字列の長さがわかっている場合 (およびそれが偶数である場合)、ISO-8859-1 文字を埋め込む 00 バイトの存在によって UTF-16 を識別することができます。(ラテン文字以外の言語でも、ASCII スペースと改行を多用します。)

ただし、ヌル終了に依存している場合、それは役に立ちません。00 00 を探すと、たまたまヌル ターミネータの直後にある 00 バイトと間接的に一致する可能性があります。さらに悪いことに、ASCII 文字列2 つのヌルで終了していない場合、文字列の末尾を超えて実行されます。

于 2010-07-18T01:48:06.167 に答える
0

シングルおよびダブル 0 バイトのチェックに基づく単純なエンコーディング検出スキームに、あるレベルのヒューリスティックを追加する 1 つの方法:

  1. 従来のライブラリから整列化された「コンテキスト」が 1 つ以上の文字列で構成されていると想定します。
  2. そのようなコンテキストの 1 つの文字列が UTF-16 である可能性が高い場合、そのコンテキストの他のすべての文字列も UTF-16 です。
  3. そのため、UTF-16 文字列が「十分に高い」確実性で見つかるとすぐに、他のすべての検出を「おそらく UTF-16」にバイアスします。
  4. 「おそらく UTF-16 ではない」文字列が「間違いなく UTF-8 ではない」文字列であることが判明した場合、それは ASCII でもあり得ないため、UTF-16 として設定します。

これにより、マネージド が正確に作成される率がはるかに高くなりますString

于 2010-06-29T13:01:37.233 に答える