2009-05-29 12 views
6

Abbiamo recentemente trovato un codice di esempio da un fornitore per l'hashing di una chiave segreta per una chiamata al servizio web, il loro campione era in VB.NET che abbiamo convertito in C#. Ciò ha causato l'hashing di produrre input diversi. Si scopre che il modo in cui stavano generando la chiave per la crittografia era convertendo un array di caratteri in una stringa e tornando a un array di byte. Ciò mi ha portato a scoprire che l'encoder predefinito di VB.NET e C# funziona diversamente con alcuni caratteri.Perché Encoding.Default.GetBytes() restituisce risultati diversi in VB.NET e 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)) 

L'uscita C# è 63, mentre VB è il valore di byte corretto di 149. se si utilizza qualsiasi altro valore, come il 145, ecc , l'uscita corrisponde.

Camminando attraverso il debug, l'encoder predefinito VB e C# è SBCSCodePageEncoding.

Qualcuno sa perché questo è?

Ho corretto il codice di esempio inizializzando direttamente un array di byte, che avrebbe dovuto essere in primo luogo, ma voglio ancora sapere perché l'encoder, che non dovrebbe essere specifico della lingua, sembra essere proprio questo.

risposta

11

Se si utilizza ChrW (149), si otterrà un risultato diverso, 63, lo stesso del C#.

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

the documentation Letto per vedere la differenza: che spiegherà la risposta

+2

Ecco un link alla documentazione: http://msdn.microsoft .com/it/us/library/613dxh46 (VS.80) .aspx –

+0

Cheers Jon: stavo proprio aggiungendo un collegamento. – RichardOD

+0

Grazie! Stavo pensando che avesse qualcosa a che fare con il bit Chr(), ma non ero sicuro di come evitare l'uso di Chr() in VB.NET. – Annagram

0

Il default encoding dipende dalla macchina e dipende dal thread poiché utilizza la tabella codici corrente. In genere si dovrebbe usare qualcosa come Encoding.UTF8 in modo che non ci si debba preoccupare di ciò che accade quando una macchina usa unicode e un'altra sta usando 1252-ANSI.

0

Diversi sistemi operativi potrebbero utilizzare codifiche diverse come predefinite. Pertanto, i dati trasmessi da un sistema operativo a un altro potrebbero essere tradotto in modo errato. Per garantire che i byte codificati vengano decodificati correttamente, l'applicazione deve utilizzare una codifica Unicode, ovvero UTF8Encoding, UnicodeEncoding o UTF32Encoding, con un preambolo. Un'altra opzione consiste nell'utilizzare un protocollo di livello superiore per garantire che lo stesso formato venga utilizzato per la codifica e la decodifica.

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

è possibile verificare ogni lingua produce quando si codifica in modo esplicito utilizzando utf8?

4

La funzione VB Chr prende un argomento nel range da 0 a 255, e lo converte in un personaggio utilizzando la tabella codici predefinita corrente. Genera un'eccezione se passi un argomento fuori da questo intervallo.

ChrW acquisirà un valore a 16 bit e restituirà il sistema corrispondente.Valore di Char senza usare una codifica - quindi darà lo stesso risultato del codice C# che hai postato.

L'equivalente approssimativo del vostro codice VB in C# senza utilizzare la classe VB Strings (che è la classe che contiene Chr e ChrW) sarebbe:

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

Credo l'equivalente in VB è ChrW (149) .

Quindi, questo codice 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))) 

produce lo stesso output come questo codice 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]); 
Problemi correlati