Codificación utilizada en el reparto de char a byte
Frecuentes
Visto 9,893 veces
7
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?
3 Respuestas
17
.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 hexadecimal0x0000
a través de una0xFFFF
y se almacena en unChar
estructura. el valor de unChar
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
4
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
1
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
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# character-encoding casting or haz tu propia pregunta.
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_222Lo 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 desanzeHe editado la respuesta, gracias por los comentarios. Parece que la comprobación de desbordamiento está desactivada de forma predeterminada. - Ant_222