Wie konvertiere ich ein Byte-Array in seinen numerischen Wert (Java)?

88

Ich habe ein 8-Byte-Array und möchte es in den entsprechenden numerischen Wert konvertieren.

z.B

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

Ich möchte eine Methode, die die obige Konvertierungsoperation ausführt.

Pirat
quelle
4
Was meinst du mit "numerischer Wert"? Stellen die Bytes eine Ganzzahl (lang) oder eine Gleitkommazahl (doppelt) in Binärform dar? Sind sie die Zeichenfolgendarstellung einer Zahl? Oder noch eine Darstellung?
Starblue
1
Dies war hilfreich: stackoverflow.com/questions/5399798/…
TacB0sS
NB: Der Link von TacB0sS war genau das, wonach ich gesucht habe - sowohl vorwärts als auch rückwärts.
Jay Taylor
new BigInteger(by).longValue()
Marquis von Lorne

Antworten:

105

Angenommen, das erste Byte ist das niedrigstwertige Byte:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Ist das erste Byte das höchstwertige, dann ist es ein bisschen anders:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Ersetzen Sie long durch BigInteger , wenn Sie mehr als 8 Bytes haben.

Vielen Dank an Aaron Digulla für die Korrektur meiner Fehler.

Mnementh
quelle
8
-1 Bytes sind vorzeichenbehaftete Werte! Und ersetze pow () durch shift (<<)! "value = (value << 8) + (von [i] & 0xff)"
Aaron Digulla
Hat der Schichtführer (<<) Vorrang von rechts nach links? Wie funktioniert der obige Code? Es funktioniert alles gut für mich. Ich will nur wissen, wie es funktioniert.
Vielen Dank
@Mnementh: Hat der Schichtoperator (<<) Vorrang von rechts nach links? Wie funktioniert der obige Code? Es funktioniert alles gut für mich. Ich will nur wissen, wie es funktioniert.
Vielen Dank
5
Falls jemand anderes das gleiche Problem hat, das ich im ersten Beispiel von [i] hatte, muss es auf einen langen Wert gesetzt werden, andernfalls funktioniert es nur für Werte unter 2 ^ 32. Das heißt,value += ((long)by[i] & 0xffL) << (8 * i);
Luke
114

Man könnte die Buffers, die als Teil des java.nioPakets bereitgestellt werden, verwenden, um die Konvertierung durchzuführen.

Hier hat das byte[]Quellarray eine Länge von 8, was der Größe entspricht, die einem longWert entspricht.

Zuerst wird das byte[]Array in a eingeschlossen ByteBuffer, und dann wird die ByteBuffer.getLongMethode aufgerufen, um den longWert zu erhalten :

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

Ergebnis

4

Ich möchte mich bei dfa für den Hinweis auf die ByteBuffer.getLongMethode in den Kommentaren bedanken .


Obwohl dies in dieser Situation möglicherweise nicht anwendbar ist, besteht die Schönheit des Buffers darin, ein Array mit mehreren Werten zu betrachten.

Wenn wir beispielsweise ein 8-Byte-Array hätten und es als zwei intWerte anzeigen wollten , könnten wir das byte[]Array in ein ByteBuffer, das als a angesehen wird, einschließen IntBufferund die Werte erhalten durch IntBuffer.get:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

Ergebnis:

1
4
Coobird
quelle
Was ist mit ByteBuffer.wrap (neues Byte [] {0, 0, 0, 1, 0, 0, 0, 4}). getLong ()? Diese Methode sollte als nächstes 8 Byte und wandelt sie in einen langen lesen
DFA
@dfa: Danke, dass du darauf hingewiesen hast, es scheint sicher zu funktionieren - ich werde die Antwort bearbeiten. :)
Coobird
16

Wenn dies ein numerischer Wert von 8 Byte ist, können Sie Folgendes versuchen:

BigInteger n = new BigInteger(byteArray);

Wenn dies ein UTF-8-Zeichenpuffer ist, können Sie Folgendes versuchen:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));
Vincent Robert
quelle
Ich hätte für diese Antwort gestimmt, wenn sie direkt nach dem ersten Codeausschnitt beendet worden wäre oder wenn sie Code zum Konvertieren der Zeichenfolge in einen "numerischen Wert" enthalten hätte. Wie es ist, scheint die zweite Hälfte Ihrer Antwort keine Folge zu sein.
Laurence Gonsalves
Nicht das, was ich ursprünglich gemeint habe, ich habe meine Antwort geändert
Vincent Robert
15

Einfach, könnten Sie verwenden oder sich darauf beziehen Guave lib von Google zur Verfügung gestellt, welche Angebote utiliy Methoden für die Konvertierung zwischen langen und Byte - Array. Mein Kundencode:

    long content = 212000607777l;
    byte[] numberByte = Longs.toByteArray(content);
    logger.info(Longs.fromByteArray(numberByte));
Chen Yi
quelle
8

Sie können BigInteger auch für Bytes variabler Länge verwenden. Sie können es in Long, Integer oder Short konvertieren, je nachdem, was Ihren Anforderungen entspricht.

new BigInteger(bytes).intValue();

oder um die Polarität zu bezeichnen:

new BigInteger(1, bytes).intValue();
Jamel Toms
quelle
1

Jede Zelle im Array wird als int ohne Vorzeichen behandelt:

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}
Asaf Pinhassi
quelle
Nur eine Anmerkung, dass ich 0xFFL verwenden musste, sonst hatte die Umwandlung von int 0xFF zu long eine ganze Menge falscher 1-Bits gesetzt, als ich Long.toHexString (l) druckte.
Luke
Sie müssen 0xFFL verwenden, sonst erhalten Sie eine Zeichenerweiterung.
Grau