2012-05-22 17 views
7

Tome un vistazo al siguiente código C# (función extraído de la función BuildProtectedURLWithValidity en http://wmsauth.org/examples):codificación utilizada en el elenco de char a byte

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; 
} 

Mi pregunta es: Lo que hace el casting de bytes a Char en términos de codificación?

Supongo que realmente no hace nada en términos de Codificación, pero eso significa que la Codificación.Default es la que se utiliza, por lo que el byte a devolver dependerá de cómo el marco codificará la cadena subyacente en el sistema operativo específico?

Y además, ¿es el parche realmente más grande que un byte (supongo que 2 bytes) y realmente omitirá el primer byte?

Estaba pensando en la sustitución de todo esto por:

Encoding.UTF8.GetBytes(stringToBeHashed) 

¿Qué opinas?

Respuesta

14

.NET Framework utiliza Unicode para representar todos sus caracteres y cadenas. El valor entero de un carácter (que puede obtener mediante conversión al int) es equivalente a su unidad de código UTF-16. Para los personajes en el plano multilingüe básico (que constituyen la mayoría de los personajes que encontrarás), este valor es el punto de código Unicode.

.NET Framework utiliza la estructura Char para representar un carácter Unicode. El estándar Unicode identifica cada carácter Unicode con un número escalar único de 21 bits llamado punto de código, y define el formulario de codificación UTF-16 que especifica cómo se codifica un punto de código en una secuencia de uno o más valores de 16 bits. Cada valor de 16 bits varía desde hexadecimal 0x0000 hasta 0xFFFF y se almacena en una estructura Char. El valor de un objeto Char es su valor numérico (ordinal) de 16 bits. - Char Structure

Al lanzar un char a byte dará lugar a la pérdida de datos para cualquier carácter cuyo valor es mayor que 255. intente ejecutar el siguiente ejemplo sencillo para entender por qué:

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 

Sí, definitivamente debe use Encoding.UTF8.GetBytes en su lugar.

4

de reparto entre byte y char es como usar la ISO-8859-1 codificación (= los primeros 256 caracteres de Unicode), excepto que en silencio pierde información cuando se codifica caracteres más allá de U + 00FF.

Y además, ¿es el parche realmente más grande que un byte (supongo que 2 bytes) y realmente omitirá el primer byte?

Sí. A C# char = unidad de código UTF-16 = 2 bytes.

1

char representa un punto de código UTF-16 de 16 bits.Lanzar un char a un byte da como resultado el byte más bajo del carácter, pero tanto Douglas y dan04 son incorrectos, ya que siempre descartará discretamente el byte más alto. Si el byte superior no es cero el resultado depende de si la opción de compilador Comprobar para la aritmética de desbordamiento/subdesbordamiento se establece:

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

de salida con la comprobación de desbordamiento:

Casting to byte character # 115: Success 
Casting to byte character # 1099: Arithmetic operation resulted in an overflow. 

de salida sin comprobación de desbordamiento:

Casting to byte character # 115: Success   
Casting to byte character # 1099: Success 
+0

Tal vez en un ambiente extraño que tira, pero creo que en la mayoría de los entornos que el caso no arroja. He probado en mi local "Microsoft (R) Visual C# Compiler versión 4.6.1590.0" y en repl.it: https://repl.it/Irlw/1. Y ambos devuelven el éxito en ambos casos (sin excepción, como muestra su resultado). –

+0

@Mariano Desanze, no puedo hablar sobre Mono, pero ¿cómo puede MS convertirlo sin error si su propia fuente de referencia muestra claramente que el carácter de entrada es [comparado] (https://referencesource.microsoft.com/#mscorlib/ system/convert.cs, fc990bd1275d43d6) (en la línea 725) a 'Byte.MaxValue' antes de la conversión, y se lanza una excepción si el valor del carácter no cabe en un byte. Mi entorno no es extraño, es simple-vainilla .NET 3.5. Descarte silencioso del byte superior es una mala idea –

+1

Entendido: Tenía la opción * Comprobar la desbordamiento/subdesbordamiento aritmético * en SharpDevelop. ¡Así que el resultado de esta conversión es ambivalente, es decir, depende de la configuración del compilador! –

Cuestiones relacionadas