c# - example - Matriz de byte a internacional
c# string to byte array (5)
Pensé que .net tenía algún tipo de método de conversión fácil de usar para convertir un int en una matriz de bytes. Hice una búsqueda rápida y todas las soluciones son un poco máscaras / cambios de un byte a la vez, como "los buenos días". ¿No hay un método ToByteArray () en alguna parte?
Esto puede ser OT, pero si está serializando una gran cantidad de tipos primitivos o estructuras POD, los Buffers del Protocolo de Google para .Net podrían serle útiles. Esto aborda el problema de endianness @Marc mencionado anteriormente, entre otras características útiles.
La mayoría de las respuestas aquí son ''UnSafe'' o no LittleEndian seguras BitConverter no es LittleEndian seguro. Así que construyendo un ejemplo here (ver la publicación de PZahra) hice una versión segura de LittleEndian simplemente leyendo la matriz de bytes en reversa cuando BitConverter.IsLittleEndian == true
void Main(){
Console.WriteLine(BitConverter.IsLittleEndian);
byte[] bytes = BitConverter.GetBytes(0xdcbaabcdfffe1608);
//Console.WriteLine(bytes);
string hexStr = ByteArrayToHex(bytes);
Console.WriteLine(hexStr);
}
public static string ByteArrayToHex(byte[] data)
{
char[] c = new char[data.Length * 2];
byte b;
if(BitConverter.IsLittleEndian)
{
//read the byte array in reverse
for (int y = data.Length -1, x = 0; y >= 0; --y, ++x)
{
b = ((byte)(data[y] >> 4));
c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(data[y] & 0xF));
c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
}
else
{
for (int y = 0, x = 0; y < data.Length; ++y, ++x)
{
b = ((byte)(data[y] >> 4));
c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(data[y] & 0xF));
c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
}
return String.Concat("0x",new string(c));
}
Devuelve esto:
True
0xDCBAABCDFFFE1608
que es el hex exacto que entró en la matriz de bytes.
La respuesta de Marc es, por supuesto, la respuesta correcta. Pero desde que mencionó los operadores de turno y el código inseguro como una alternativa. Me gustaría compartir una alternativa menos común. Usar una estructura con diseño Explicit
. Esto es similar en principio a una union
C / C ++.
Aquí hay un ejemplo de una estructura que se puede usar para llegar a los bytes componentes del tipo de datos Int32 y lo bueno es que es bidireccional, puede manipular los valores de bytes y ver el efecto en el Int.
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct Int32Converter
{
[FieldOffset(0)] public int Value;
[FieldOffset(0)] public byte Byte1;
[FieldOffset(1)] public byte Byte2;
[FieldOffset(2)] public byte Byte3;
[FieldOffset(3)] public byte Byte4;
public Int32Converter(int value)
{
Byte1 = Byte2 = Byte3 = Byte4 = 0;
Value = value;
}
public static implicit operator Int32(Int32Converter value)
{
return value.Value;
}
public static implicit operator Int32Converter(int value)
{
return new Int32Converter(value);
}
}
Lo anterior ahora se puede usar de la siguiente manera
Int32Converter i32 = 256;
Console.WriteLine(i32.Byte1);
Console.WriteLine(i32.Byte2);
Console.WriteLine(i32.Byte3);
Console.WriteLine(i32.Byte4);
i32.Byte2 = 2;
Console.WriteLine(i32.Value);
Por supuesto, la policía de inmutabilidad puede no estar entusiasmada con la última posibilidad :)
Si viniste aquí desde Google
La respuesta alternativa a una pregunta anterior se refiere a la biblioteca de John Skeet que tiene herramientas para permitirle escribir tipos de datos primitivos directamente en un byte [] con un desplazamiento del índice. Mucho mejor que BitConverter
si necesitas rendimiento.
Un hilo viejo discutiendo este tema aquí
Las bibliotecas de John Skeet están aquí
Simplemente descargue la fuente y mire el espacio de nombres MiscUtil.Conversion
. EndianBitConverter.cs
maneja todo por ti.
Supongo que Microsoft no ha implementado esto porque .NET Framework es el código DeFacto Safe. Pero parece ridículo que miles de personas tengan que hacer cambios de bit o ir a una biblioteca de terceros para satisfacer una necesidad tan básica.
byte[] bytes = BitConverter.GetBytes(i);
aunque tenga en cuenta también que es posible que desee comprobar BitConverter.IsLittleEndian
para ver qué camino va a aparecer.
Tenga en cuenta que si lo hace de forma repetida, es posible que desee evitar todas las asignaciones de conjuntos de corta vida escribiéndolo usted mismo a través de las operaciones de cambio ( >>
/ <<
) o mediante el uso de unsafe
código unsafe
. Las operaciones de cambio también tienen la ventaja de que no se ven afectadas por la permanencia de su plataforma; siempre obtienes los bytes en el orden que esperas.