2009-05-29 11 views
6

Wir sind kürzlich auf einen Beispielcode eines Anbieters zum Hashing eines geheimen Schlüssels für einen Webdienstanruf gestoßen, deren Beispiel in VB.NET enthalten war und in C# konvertiert wurde. Dies führte dazu, dass das Hashing unterschiedliche Eingaben erzeugte. Es stellte sich heraus, dass die Art und Weise, wie sie den Schlüssel für die Verschlüsselung erzeugten, durch die Umwandlung eines char-Arrays in eine Zeichenfolge und zurück in ein Byte-Array erfolgte. Dies führte mich zu der Entdeckung, dass der Standard-Encoder von VB.NET und C# bei einigen Zeichen anders funktioniert.Warum Encoding.Default.GetBytes() gibt verschiedene Ergebnisse in VB.NET und C# zurück?

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)) 

Die C# Ausgabe 63 ist, während VB der korrekte Byte-Wert von 149. , wenn Sie einen anderen Wert verwenden ist, wie 145, usw. , die Ausgabe stimmt überein.

Wenn Sie durch das Debugging gehen, ist sowohl der VB- als auch der C# -Endcodierer SBCSCodePageEncoding.

Weiß jemand, warum das ist?

Ich habe den Beispielcode korrigiert, indem ich ein Byte-Array direkt initialisiert habe, was eigentlich hätte sein sollen, aber ich möchte immer noch wissen, warum der Encoder, der nicht sprachspezifisch sein sollte, genau das ist.

Antwort

11

Wenn Sie ChrW (149) verwenden, erhalten Sie ein anderes Ergebnis - 63, das gleiche wie das C#.

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

lesen the documentation die Differenz-, um zu sehen, dass die Antwort

+2

Hier ist ein Link auf die Dokumentation: http://msdn.microsoft .com/de-us/library/613dxh46 (VS.80) .aspx –

+0

Prost Jon- Ich war gerade dabei, einen Link hinzuzufügen. – RichardOD

+0

Danke! Ich dachte, es hätte etwas mit dem Chr() - Bit zu tun, aber ich war mir nicht sicher, wie ich die Verwendung von Chr() in VB.NET vermeiden konnte. – Annagram

0

Die default encoding ist maschinenabhängig sowie threadabhängig, da sie die aktuelle Codepage verwendet. Im Allgemeinen sollten Sie etwas wie Encoding.UTF8 verwenden, damit Sie sich keine Gedanken darüber machen müssen, was passiert, wenn eine Maschine Unicode verwendet und eine andere 1252-ANSI verwendet.

0

Verschiedene Betriebssysteme verwenden möglicherweise verschiedene Kodierungen als Standard. Daten, die von einem Betriebssystem zu einem anderen gestreamt werden, könnten daher falsch übersetzt werden. Um sicherzustellen, dass die codierten Bytes richtig decodiert werden, sollte Ihre Anwendung eine Unicode-Codierung verwenden, dh UTF8Encoding, UnicodeEncoding oder UTF32Encoding, mit einer Präambel. Eine andere Option ist die Verwendung eines übergeordneten Protokolls, um sicherzustellen, dass das gleiche Format für die Codierung und die Decodierung verwendet wird.

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

können Sie überprüfen, welche jede Sprache erzeugt, wenn Sie explizit mit UTF-8-Codierung?

4

Die VB Chr Funktion ein Argument im Bereich 0 bis 255 nimmt erklären wird, und wandelt sie in ein Zeichen der aktuelle Standard-Codepage verwenden. Es wird eine Ausnahme ausgelöst, wenn Sie ein Argument außerhalb dieses Bereichs übergeben.

ChrW nimmt einen 16-Bit-Wert und gibt das entsprechende System zurück.Char-Wert ohne Verwendung einer Kodierung - daher wird das gleiche Ergebnis wie der von Ihnen gepostete C# -Code erhalten.

Die ungefähre Entsprechung Ihrer VB-Code in C#, ohne dass die VB Strings-Klasse (das ist die Klasse, die Chr und ChrW enthält) wäre:

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

ich das Äquivalent in VB glauben ChrW (149) .

Also, der VB-Code ...

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))) 

die gleiche Ausgabe wie diese C# -Code ...

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]); 
Verwandte Themen