7

次のC#コード( http://wmsauth.org/examplesの関数から抽出された関数)を見BuildProtectedURLWithValidityてください。

byte[] StringToBytesToBeHashed(string to_be_hashed) {
    byte[] to_be_hashed_byte_array = new byte[to_be_hashed.Length];
    int i = 0;
    foreach (char cur_char in to_be_hashed)
    {
        to_be_hashed_byte_array[i++] = (byte)cur_char;
    }
    return to_be_hashed_byte_array;
}

私の質問は、バイトから文字へのキャストはエンコーディングに関して何をするのかということです。

エンコーディングに関しては実際には何もしないと思いますが、それはEncoding.Defaultが使用されることを意味するので、返されるバイトは、フレームワークが特定のオペレーティングシステムで基になる文字列をエンコードする方法に依存しますか?

その上、charは実際には1バイトよりも大きく(私は2バイトだと思います)、実際には最初のバイトを省略しますか?

私はこれをすべて次のように置き換えることを考えていました:

Encoding.UTF8.GetBytes(stringToBeHashed)

どう思いますか?

4

3 に答える 3

17

.NET Frameworkは、Unicodeを使用してすべての文字と文字列を表します。charの整数値(にキャストすることで取得できますint)は、そのUTF-16コード単位と同等です。基本多言語面(これまでに遭遇する文字の大部分を構成する)の文字の場合、この値はUnicodeコードポイントです。

.NET Frameworkは、このChar構造を使用してUnicode文字を表します。Unicode標準は、コードポイントと呼ばれる一意の21ビットスカラー番号で各Unicode文字を識別し、コードポイントを1つ以上の16ビット値のシーケンスにエンコードする方法を指定するUTF-16エンコード形式を定義します。各16ビット値の範囲は16進数0x0000から0xFFFFであり、構造体に格納されCharます。オブジェクトの値は、Charその16ビットの数値(序数)です。—文字の構造

chartoをキャストするbyteと、値が255より大きい文字のデータが失われます。次の簡単な例を実行して、理由を理解してください。

char c1 = 'D';        // code point 68
byte b1 = (byte)c1;   // b1 is 68

char c2 = 'ń';        // code point 324
byte b2 = (byte)c2;   // b2 is 68 too!
                      // 324 % 256 == 68

はい、代わりに必ず使用する必要がありますEncoding.UTF8.GetBytes

于 2012-05-22T19:18:47.553 に答える
4

byteとの間のキャストは、 ISO-8859-1エンコーディング(= Unicodeの最初の256文字)charを使用するのと似ていますが、U+00FFを超える文字をエンコードするときに情報がサイレントに失われる点が異なります。

さらに、charは実際には1バイトよりも大きく(2バイトと推測しています)、実際には最初のバイトが省略されますか?

はい。AC#char=UTF-16コード単位=2バイト。

于 2012-05-22T19:26:00.217 に答える
1

char16ビットUTF-16コードポイントを表します。charaをキャストするとbyte、文字の下位バイトになりますが、ダグラスdan04はどちらも、常に上位バイトを静かに破棄するという点で間違っています。上位バイトがゼロでない場合、結果は、コンパイラオプションの算術オーバーフロー/アンダーフローのチェックが設定されているかどうかによって異なります。

using System;
namespace CharTest
{
    class Program
    {
        public static void Main(string[] args)
        {   ByteToCharTest( 's' );
            ByteToCharTest( 'ы' );

            Console.ReadLine();
        }

        static void ByteToCharTest( char c )
        {   const string MsgTemplate =
                "Casting to byte character # {0}: {1}";

            string msgRes;
            byte   b;

            msgRes = "Success";
            try
            {   b = ( byte )c;  }
            catch( Exception e )
            {   msgRes = e.Message;  }

            Console.WriteLine(
                String.Format( MsgTemplate, (Int16)c, msgRes ) );
        }
    }
}

オーバーフローチェック付きの出力:

Casting to byte character # 115: Success
Casting to byte character # 1099: Arithmetic operation resulted in an overflow.

オーバーフローチェックなしの出力:

Casting to byte character # 115: Success        
Casting to byte character # 1099: Success
于 2017-06-17T17:03:53.780 に答える