2009-05-29 254 views
6

我們最近遇到了一些供應商的示例代碼,用於散列Web服務調用的密鑰,他們的示例是在我們轉換爲C#的VB.NET中。這導致哈希產生不同的輸入。事實證明,他們爲加密生成密鑰的方式是將char數組轉換爲字符串並返回到字節數組。這讓我發現VB.NET和C#的默認編碼器與某些字符的工作方式不同。爲什麼Encoding.Default.GetBytes()在VB.NET和C#中返回不同的結果?

C#:

Console.Write(Encoding.Default.GetBytes(new char[] { (char)149 })[0]); 

VB:

Dim b As Char() = {Chr(149)} 
Console.WriteLine(Encoding.Default.GetBytes(b)(0)) 

C#的輸出爲63,而VB是149 如果你使用任何其他值,如145等正確的字節值,輸出匹配。

通過調試,VB和C#默認編碼器都是SBCSCodePageEncoding。

有誰知道這是爲什麼?

我已經通過直接初始化一個字節數組來糾正示例代碼,它應該放在第一位,但我仍然想知道爲什麼編碼器不應該是語言特定的,看起來就是這樣。

回答

11

如果你使用ChrW(149),你會得到一個不同的結果63,和C#一樣。

Dim b As Char() = {ChrW(149)} 
Console.WriteLine(Encoding.Default.GetBytes(b)(0)) 

the documentation看到,將解釋答案

+2

下面是對文件的鏈接:http://msdn.microsoft .com/en-us/library/613dxh46(VS.80).aspx – 2009-05-29 19:25:47

0

default encoding是機器相關的,也取決於線程,因爲它使用當前的代碼頁。你通常應該使用像Encoding.UTF8這樣的東西,這樣你就不必擔心當一臺機器使用unicode而另一臺機器使用1252-ANSI時會發生什麼。

0

不同的操作系統可能會使用 不同的編碼作爲默認值。 因此,從一個 操作系統到另一個操作系統的數據流可能被 翻譯不正確。爲確保 的編碼字節正確解碼爲 ,您的應用程序應使用一個Unicode編碼,即 UTF8Encoding,UnicodeEncoding或 UTF32Encoding,並帶有前導碼。 另一種選擇是使用更高級別的協議來確保 使用相同的格式來編碼 並進行解碼。

http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx

你可以查閱一下每種語言產生,當你明確地編碼使用UTF8?

4

的VB Chr函數需要一個參數,在0至255的範圍內difference-,並將其轉換爲使用當前的默認代碼頁的字符。如果你在這個範圍之外傳遞一個參數,它會拋出異常。

ChrW將採取一個16位值並返回相應的系統。不使用編碼的字符值 - 因此會得到與您發佈的C#代碼相同的結果。

在C#中的VB代碼的大致相當於不使用VB字符串類(這是一個包含人權委員會和CHRW類)是:

char[] chars = Encoding.Default.GetChars(new byte[] { 149 }); 
Console.Write(Encoding.Default.GetBytes(chars)[0]); 
0

相信在VB相當於是CHRW(149) 。

所以,這個VB代碼...

Dim c As Char() = New Char() { Chr(149) } 
    'Dim c As Char() = New Char() { ChrW(149) } 
    Dim b As Byte() = System.Text.Encoding.Default.GetBytes(c) 
    Console.WriteLine("{0}", Convert.ToInt32(c(0))) 
    Console.WriteLine("{0}", CInt(b(0))) 

產生輸出作爲此C#代碼一樣...

var c = new char[] { (char)149 }; 
    var b = System.Text.Encoding.Default.GetBytes(c); 
    Console.WriteLine("{0}", (int)c[0]); 
    Console.WriteLine("{0}", (int) b[0]); 
相關問題