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.


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


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.


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

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"));

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


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();


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;
}

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.