2010-07-20 3 views
12

Sto provando a trasmettere un array da 4 byte a un ulong in C#. Attualmente sto usando questo codice:C# Big-endian ulong da 4 byte

atomSize = BitConverter.ToUInt32(buffer, 0); 

Il byte [4] contiene questo:

0 0 0 32

Tuttavia, i byte sono big-endian. C'è un modo semplice per convertire questo big-endian ulong in un little-endian ulong?

risposta

18

Credo che EndianBitConverter nella libreria MiscUtil di Jon Skeet (nuget link) possa fare ciò che si desidera.

Si potrebbe anche scambiare i bit utilizzando le operazioni di scorrimento di bit:

uint swapEndianness(uint x) 
{ 
    return ((x & 0x000000ff) << 24) + // First byte 
      ((x & 0x0000ff00) << 8) + // Second byte 
      ((x & 0x00ff0000) >> 8) + // Third byte 
      ((x & 0xff000000) >> 24); // Fourth byte 
} 

Usage:

atomSize = BitConverter.ToUInt32(buffer, 0); 
atomSize = swapEndianness(atomSize); 
+1

Grazie, forse potresti mostrarmi cosa stai facendo per linea? Sarebbe fantastico, non ho mai usato il bit shifting fino ad ora. – WesleyE

+1

@WesleyE: l'ho riscritto per renderlo un po 'più chiaro. Gestisce un byte alla volta, maschera gli 8 bit e poi si sposta nella loro nuova posizione. I quattro byte vengono quindi aggiunti insieme per fornire il risultato. Se non capisci cos'è il bitshifting, ti consiglio di rispondere a questa domanda + risposta: http://stackoverflow.com/questions/141525/absolute-beginners-guide-to-bit-shifting –

+1

È più veloce rimuovere le and-operations e cast a byte ogni volta. – usr

6

System.Net.IPAddress.NetworkToHostOrder(atomSize); sarà capovolgere le byte.

+2

Non necessariamente. Se il tuo host è già big-endian, non verrà apportata alcuna modifica. –

+0

Non importa, Jeff. Il punto è che se il sistema è già big endian, BitConverter lo leggerà come BigEndian e non sarà necessario alcun cambiamento. Sfortunatamente, l'uso di questa funzione o del convertito di Jon può comportare gravi penalizzazioni delle prestazioni , se si dice che si sta lavorando con un file che contiene centinaia di migliaia di essi. Se questo è il caso, si dovrebbe andare con il suggerimento di Mark Byers. L'unico modo per ottenere più velocemente è quello di fare funzioni specifiche della CPU, ad esempio x86 ha l'istruzione di assemblaggio BSWAP che è molto più veloce del cambio di bit. Questa funzione è perfettamente soddisfacente per l'elaborazione dei pacchetti – Rahly

4

Si consiglia di utilizzare Mono's DataConvert che è come BitConverter su steroidi. Permette di leggere direttamente in array di byte big-endian e migliora notevolmente su BitConverter.

Un collegamento diretto alla sorgente è here.

+0

Il link sorgente è rotto – mpen

+1

Localizzazione della fonte fissa (sembra che si siano spostati su github: D) –

0
firstSingle = BitConverter.ToSingle(buffer,0); 
secondSingle = BitConverter.ToSingle(buffer,2); 

var result = BitConverter.ToUInt32(BitConverter.GetBytes(secondSingle).Concat(BitConverter.GetBytes(firstSingle).ToArray()); 
4
BitConverter.ToUInt32(buffer.Reverse().ToArray(), 0) 

No?

+0

Non esattamente, avresti bisogno di una chiamata 'ToArray()'. –

+0

Non proprio la stessa cosa, se il tuo buffer è maggiore di 4, allora otterrai gli ultimi byte scambiati. Invece di 0, buffer.Length-4. – Rahly

1

Questo può essere vecchio ma sono sorpreso che nessuno si avvicinò con questa risposta più semplice ancora, richiede solo una linea ...

// buffer is 00 00 00 32 
Array.Reverse(buffer); 
// buffer is 32 00 00 00 
atomSize = BitConverter.ToUInt32(buffer, 0); 

sto usando per confrontare i risultati generati in C# (poco -endiano) con checksum generati in Java (big-endian).

+0

Non è la stessa cosa. se il buffer è 00 00 00 32 54, allora il tuo buffer è dopo il reverse è 54 32 00 00 00, quindi un ToUInt32 non ti darà il valore 32. Se il tuo buffer è sempre la lunghezza 4 allora funzionerà bene. Per farlo funzionare funziona per diverse lunghezze, avresti bisogno di Lunghezza-4 invece di 0 dopo il Reverse. – Rahly

+0

L'argomento è "C# Big-endian ulong da 4 byte", e questa era la mia risposta specifica alla domanda, non ho mai detto che fosse una soluzione per ogni caso, ma per tipi di dati numerici definiti (16-bit, 32-bit , 64-bit, ecc.) È sufficiente fintanto che l'array di byte di destinazione ha lo stesso numero di byte. – IaguCool