2012-05-22 83 views
7

看看下面的C#代碼(從BuildProtectedURLWithValidity功能http://wmsauth.org/examples提取功能):編碼爲字節

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是使用的那個,因此返回的字節將取決於框架如何編碼底層字符串特定的操作系統?

此外,是字符實際上比一個字節大(我猜2字節),實際上會省略第一個字節?

Encoding.UTF8.GetBytes(stringToBeHashed) 

你怎麼想:

我在通過更換這一切都在想什麼?

回答

14

.NET Framework使用Unicode來表示其所有字符和字符串。 char的整數值(可以通過轉換爲int獲得)等同於其UTF-16代碼單元。對於基本多語言平面中的字符(它構成了您將遇到的大多數字符),該值是Unicode代碼點。

.NET Framework使用Char結構來表示Unicode字符。 Unicode標準使用稱爲代碼點的唯一21位標量數來標識每個Unicode字符,並定義UTF-16編碼形式,該形式指定如何將代碼點編碼爲一個或多個16位值的序列。每個16位值的範圍從十六進制0x00000xFFFF,並存儲在一個Char結構中。 Char對象的值是其16位數字(有序)值。 - Char Structure

鑄造一個charbyte將導致其價值是任何字符數據丟失大於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

4

bytechar之間投射就像使用ISO-8859-1編碼(= Unicode的前256個字符),除了編碼U + 00FF以外的字符時它會自動丟失信息。

此外,是字符實際上比一個字節大(我猜2字節),實際上會省略第一個字節?

是的。 A C#char = UTF-16代碼單元= 2個字節。

1

char代表16位UTF-16碼點。將char轉換爲byte會導致字符的低位字節,但Douglasdan04都是錯誤的,因爲它總是會安靜地丟棄高位字節。如果高字節不是0的結果取決於是否編譯器選項檢查算術溢出/下溢設置:

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 
+0

也許在一些奇怪的環境中它會拋出,但我認爲在大多數情況下不會拋出。我已在本地「Microsoft(R)Visual C#編譯器版本4.6.1590.0」和repl.it中進行了測試:https://repl.it/Irlw/1。兩種情況下都能成功(沒有例外,就像輸出結果一樣)。 –

+0

@Mariano Desanze,我不能告訴Mono,但是如果MS自己的參考源清楚地表明輸入字符[比較](https://referencesource.microsoft.com/#mscorlib/ system/convert.cs,fc990bd1275d43d6)(在第725行)轉換爲'Byte.MaxValue',如果char的值不適合字節,則拋出異常? 我的環境並不奇怪 - 這是純粹的香草.NET 3.5。 高級字節的無聲丟棄是一個壞主意 –

+1

明白了:我在SharpDevelop中檢查了算術溢出/下溢*選項。所以這種轉換的結果是矛盾的,即取決於編譯器設置! –