Codificación utilizada en el reparto de char a byte

Eche un vistazo al siguiente código C# (función extraída de la BuildProtectedURLWithValidity Funcionar en http://wmsauth.org/examples):

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: ¿Qué hace la conversión de byte a char en términos de codificación?

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

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

Estaba pensando en reemplazar todo esto por:

Encoding.UTF8.GetBytes(stringToBeHashed)

¿Qué piensas?

preguntado el 22 de mayo de 12 a las 20:05

3 Respuestas

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

.NET Framework utiliza el Char estructura 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 formato 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 va desde hexadecimal 0x0000 a través de una 0xFFFF y se almacena en un Char estructura. el valor de un Char objeto es su valor numérico (ordinal) de 16 bits. — Estructura de caracteres

Emitiendo un char a byte dará como resultado la pérdida de datos para cualquier carácter cuyo valor sea mayor que 255. Intente ejecutar el siguiente ejemplo simple para comprender 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 deberías usar Encoding.UTF8.GetBytes preferiblemente.

Respondido 15 Abr '16, 16:04

Casting entre byte y char es como usar el ISO-8859-1 (= los primeros 256 caracteres de Unicode), excepto que pierde información silenciosamente al codificar caracteres más allá de U+00FF.

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

Si. C.A# char = Unidad de código UTF-16 = 2 bytes.

contestado el 22 de mayo de 12 a las 20:05

char representa un punto de código UTF-16 de 16 bits. lanzando un char a una byte da como resultado el byte más bajo del carácter, pero ambos Douglas y dan04 están equivocados en el sentido de que siempre descartará silenciosamente el byte más alto. Si el byte más alto no es cero, el resultado depende de si la opción del compilador Compruebe si hay desbordamiento o subdesbordamiento aritmético Está establecido:

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

Salida con verificación de desbordamiento:

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

Salida sin verificación de desbordamiento:

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

Respondido el 19 de junio de 17 a las 23:06

Tal vez en algún entorno extraño arroja, pero creo que en la mayoría de los entornos ese caso no arroja. He probado en mi "Microsoft (R) Visual C# Compiler version 4.6.1590.0" local y en repl.it: repl.it/Irlw/1 . Y ambos devuelven el éxito en ambos casos (sin excepción, como muestra su salida). - mariano desanze

@Mariano Desanze, no puedo decir 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 en comparación con(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 y sencillo .NET 3.5. El descarte silencioso del byte más alto es una mala idea - Ant_222

Lo tengo: tenía el Compruebe si hay desbordamiento o subdesbordamiento aritmético opción activada en SharpDevelop. Entonces, el resultado de esta conversión es ambivalente, es decir, ¡depende de la configuración del compilador! - Ant_222

En ese caso, perdón por el voto negativo. Lo revertiré si edita su respuesta, ya que no puedo hacerlo de otra manera (tal vez pueda aclarar que no se lanzará en todos los entornos). Pero esto es realmente extraño, porque incluso en el intérprete en línea en microsoft.com/net puedes poner char c = 'ы'; Console.WriteLine((byte)c); y vea que devuelve "75" en lugar de una excepción. - mariano desanze

He editado la respuesta, gracias por los comentarios. Parece que la comprobación de desbordamiento está desactivada de forma predeterminada. - Ant_222

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.