Int a matrice di byte
Domanda
ho pensato .net avuto un qualche tipo di facile metodo di conversione da utilizzare per la conversione di un int in un array di byte? Ho fatto una ricerca rapida e tutte le soluzioni sono mascheramento di bit / spostando un byte alla volta, come "il buon vecchio giorni". Non c'è una ToByteArray () il metodo da qualche parte?
Soluzione
byte[] bytes = BitConverter.GetBytes(i);
anche se noti inoltre che è potrebbe voler controllare BitConverter.IsLittleEndian
per vedere quale modo per aggirare che sta per apparire!
Si noti che se si sta facendo questo più volte si potrebbe voler evitare tutte quelle di breve durata allocazioni matrice scrivendo da soli tramite sia le operazioni di spostamento (>>
/ <<
), oppure utilizzando il codice unsafe
. operazioni di scorrimento anche hanno il vantaggio che essi non sono interessati da endianness della vostra piattaforma; si sempre ottenere i byte nell'ordine in cui li aspettano.
Altri suggerimenti
La risposta di Marc è, naturalmente, la risposta giusta. Ma dal momento che ha ricordato gli operatori di spostamento e il codice non sicuro come alternativa. Vorrei condividere un'alternativa meno comune. Utilizzando una struttura con il layout Explicit
. Questo è simile in linea di principio ad un C / C ++ union
.
Ecco un esempio di una struttura che può essere utilizzato per raggiungere i byte che compongono il tipo di dati Int32 e la cosa bella è che è a due vie, è possibile manipolare i valori di byte e vedere l'effetto sul 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 lattina sopra ora essere utilizzato come segue
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);
Naturalmente la polizia immutabilità potrebbe non essere entusiasti l'ultima possiblity:)
Questo può essere OT, ma se si serializzare un sacco di tipi primitivi o strutture POD, Google protocollo Tamponi per .Net potrebbe essere utile a voi. Questo indirizzi la questione endianness @ Marc sollevate sopra, tra le altre caratteristiche utili.
Se sei arrivato qui da Google
risposta alternativa a una domanda più vecchio si riferisce alla Biblioteca di John Skeet che ha gli strumenti per far si scrive tipi di dati primitivi direttamente in un byte [] con un Indice compensata. Molto meglio di quanto BitConverter
se avete bisogno di prestazioni.
più vecchio discutere la questione qui
Biblioteche di Basta scaricare il sorgente e sguardo al namespace MiscUtil.Conversion
. maniglie EndianBitConverter.cs
tutto per voi.
La maggior parte delle risposte qui sono o 'non sicuro" o non è sicuro LittleEndian. BitConverter non è sicuro LittleEndian. Quindi, sulla base di un esempio nel qui (vedi il post da PZahra) ho fatto una versione sicura LittleEndian semplicemente leggendo l'array di byte in retromarcia quando 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));
}
Si restituisce questo:
True
0xDCBAABCDFFFE1608
che è l'esagono esatto che è andato in byte.