Int para el conjunto de bytes
Pregunta
pensé .net tenían algún tipo de método de conversión fácil de usar para convertir un entero en una matriz de bytes? Hice una búsqueda rápida y todas las soluciones están bit de marca / desplazar un byte a la vez, como "los buenos viejos días". ¿No hay una ToByteArray () en algún método?
Solución
byte[] bytes = BitConverter.GetBytes(i);
A pesar de destacar también que podría que desee comprobar BitConverter.IsLittleEndian
para ver qué forma de evitar eso va a aparecer!
Tenga en cuenta que si usted está haciendo esto varias veces es posible que desee evitar todos esos efímeros asignaciones arreglo escribiendo usted mismo a través de cualquiera de las operaciones de cambio (>>
/ <<
), o mediante el uso de código de unsafe
. Las operaciones de desplazamiento también tiene la ventaja de que no se ven afectadas por orden de bits de su plataforma; que siempre obtener los bytes en el orden en que se esperan.
Otros consejos
La respuesta de Marc es por supuesto la respuesta correcta. Pero desde que mencionó los operadores de desplazamiento y de código no seguro como una alternativa. Me gustaría compartir una alternativa menos común. El uso de una estructura con la disposición Explicit
. Esto es similar en principio a union
una C / C ++.
Este es un ejemplo de una estructura que se puede utilizar para llegar a los bytes que componen el tipo de datos Int32 y lo bueno es que se trata de dos vías, puede manipular los valores de byte 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);
}
}
La lata encima ahora ser utilizado como sigue
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 inmutabilidad no puede ser excitado sobre la última posibilidad:)
Esto puede ser OT pero si usted está serializando una gran cantidad de tipos primitivos o estructuras vaina, Google Protocol Buffers para .Net podría ser útil para usted. Esto se refiere a la cuestión endianness @Marc elevan por encima de, entre otras características útiles.
Si usted vino aquí desde Google
Alternativa respuesta a una pregunta de más edad se refiere a la biblioteca de John Skeet que tiene herramientas para dejar de escribir tipos de datos primitivos directamente en un byte [] con un índice de desplazamiento. Mucho mejor que BitConverter
si necesita rendimiento.
antigua discusión de este tema aquí
Bibliotecas de Sólo tienes que descargar la fuente y la mirada en el espacio de nombres MiscUtil.Conversion
. manijas EndianBitConverter.cs
todo para usted.
La mayoría de las respuestas aquí son o bien 'inseguros" o no segura LittleEndian. BitConverter no es seguro LittleEndian. Así que sobre la base de un ejemplo en el aquí (ver el mensaje por PZahra) hice una versión segura LittleEndian simplemente mediante la lectura de la matriz de bytes a la inversa 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 la siguiente:
True
0xDCBAABCDFFFE1608
que es el hexadecimal exacto en que entró en la matriz de bytes.