2009-05-29 38 views
6

Recientemente encontramos un código de muestra de un proveedor para hashir una clave secreta para una llamada al servicio web, su muestra estaba en VB.NET que convertimos a C#. Esto causó que el hash produjera entradas diferentes. Resulta que la forma en que generaban la clave para el cifrado era convirtiendo una matriz char en una cadena y volviendo a una matriz de bytes. Esto me llevó al descubrimiento de que el codificador predeterminado de VB.NET y C# funciona de manera diferente con algunos caracteres.¿Por qué Encoding.Default.GetBytes() devuelve resultados diferentes en VB.NET y 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)) 

El C# de salida es de 63, mientras que VB es el valor adecuado de bytes de 149. si se utiliza cualquier otro valor, como el 145, etc. , el resultado coincide.

Al recorrer la depuración, tanto el codificador predeterminado de VB como el de C# son SBCSCodePageEncoding.

¿Alguien sabe por qué es esto?

He corregido el código de ejemplo inicializando directamente una matriz de bytes, lo que debería haber sido, en primer lugar, pero todavía quiero saber por qué el codificador, que no debe ser un lenguaje específico, parece ser sólo eso.

Respuesta

11

Si usa ChrW (149) obtendrá un resultado diferente, 63, el mismo que el C#.

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

Leer the documentation para ver la diferencia- que explicará la respuesta

+2

Aquí hay un enlace a la documentación: http://msdn.microsoft .com/en-us/library/613dxh46 (VS.80) .aspx –

+0

Saludos Jon- Estaba en el proceso de agregar un enlace. – RichardOD

+0

Gracias! Estaba pensando que tenía algo que ver con el bit Chr(), pero no estaba seguro de cómo evitar el uso de Chr() en VB.NET. – Annagram

0

El default encoding es dependiente de la máquina y del hilo porque utiliza la página de códigos actual. Por lo general, debe usar algo como Encoding.UTF8 para que no tenga que preocuparse por lo que sucede cuando una máquina utiliza unicode y otra usa 1252-ANSI.

0

Los diferentes sistemas operativos pueden usar codificaciones diferentes por defecto. Por lo tanto, los datos transmitidos desde un sistema operativo a otro pueden ser traducidos incorrectamente. Para asegurar que los bytes codificados se decodifican correctamente, su aplicación debe utilizar una codificación Unicode, es decir, UTF8Encoding, UnicodeEncoding o UTF32Encoding, con un preámbulo. Otra opción es utilizar un protocolo de nivel superior para garantizar que tenga el mismo formato para codificar y decodificar.

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

puede comprobar lo que cada lengua produce al codificar explícitamente el uso de UTF-8?

4

La función VB Chr toma un argumento en el rango de 0 a 255, y la convierte en un personaje utilizando la página de códigos predeterminada. Arrojará una excepción si pasa un argumento fuera de este rango.

ChrW tomará un valor de 16 bits y devolverá el sistema correspondiente.Valor de Char sin usar una codificación; por lo tanto, dará el mismo resultado que el código de C# que publicó.

El equivalente aproximado de su código de VB en C# sin utilizar la clase VB Cuerdas (que es la clase que contiene Chr y ChrW) sería:

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

Creo que el equivalente en VB es ChrW (149) .

Por lo tanto, este código 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 el mismo resultado que el código 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]); 
Cuestiones relacionadas