6

私は.NETでランダムな文字列を生成してバイトに変換しようとしていますが、少し難しいです。可能な文字の完全なセットが欲しいのですが、文字列には任意の文字を含めることができると理解しています。

私のコードは現在次のとおりです。

var plainText = new StringBuilder();
for (int j = 0; j < stringLength; ++j)
{
    plainText.Append((char)_random.Next(char.MinValue, char.MaxValue));
}
byte[] x = Encoding.Unicode.GetBytes(plainText.ToString());
string result = Encoding.Unicode.GetString(x);

理論的には、plainTextresultは同一である必要があります。それらはほとんど同じですが、元の文字の一部が失われており、55000 ~ 57000 の範囲の文字のようです - それらは文字 65533 に置き換えられています。

問題はエンコーディングにあると思いますが、Unicode がこれを適切に処理すると思いました。UTF8 と UTF32 を試しましたが、同じ問題が発生します。

何かご意見は?

4

2 に答える 2

9

問題は、Unicode サロゲート文字と呼ばれる 0xD800 ~ 0xDFFF (55296 ~ 57343) の範囲の文字が、単独では有効でないことです。(UTF-16 エンコード方式で) 有効であるためには、ペア (0xD800-0xDBFF が最初、0xDC00-0xDFFF が 2 番目) として表示される必要があります。単独では、無効な文字として扱われ、0xFFFD (65533) にデコードされます。C# は文字列を表すために UTF-16 を使用するため、その出力が表示されます。

それらを除外する (たとえば、非サロゲート文字を取得するまで呼び出す_random.Next) か、サロゲート文字を生成するたびに正当なサロゲート ペアを生成するかを選択できます。

于 2012-08-26T05:36:29.543 に答える
2

これらは代理文字 55296-57343 (0xD800-0xDFFF) です。それらを正しくペアリングする必要があります。UTF-16 のサロゲート文字のペアは、単一の Unicode コードポイントを表します。

char と code-point は同じものであるという前提で動作しているようです。それは正しくありません。2^16 を超えるコードポイントがあります。

UTF-16 ウィキペディアの記事を読むことをお勧めします。

于 2012-08-26T05:37:45.040 に答える