2017-06-30 3 views
0

Ich schreibe in ein Speicherformat, das Uint32 hat, mit einem maximal zulässigen Wert von "4294967295".Java Uint32 (so lange gespeichert) zu 4 Byte-Array

Integer in Java ist natürlich knapp unter der Hälfte bei "2147483647". Also muss ich entweder Long oder Guavas UnsignedInteger verwenden.

in dieses Format zu schreiben, muss die Byte-Array-Länge 4, um die Integer passt ganz gut, aber lange auf ein Byte-Array-Umwandlung erfordert eine Reihe von Länge 8.

Wie kann ich eine lange konvertieren oder UnsignedInteger, der einen Maximalwert von "4294967295" als 4-Byte-Array darstellt?

Antwort

2

einfach es zu einem 8-Array Byte konvertieren und dann nur die letzten 4 Bytes:

public static byte[] fromUnsignedInt(long value) 
{ 
    byte[] bytes = new byte[8]; 
    ByteBuffer.wrap(bytes).putLong(value); 

    return Arrays.copyOfRange(bytes, 4, 8); 
} 

dies rückgängig zu machen Sie die folgende Methode verwenden:

public static long toUnsignedInt(byte[] bytes) 
{ 
    ByteBuffer buffer = ByteBuffer.allocate(8).put(new byte[]{0, 0, 0, 0}).put(bytes); 
    buffer.position(0); 

    return buffer.getLong(); 
} 

Beachten Sie, dass diese Methode Nimm ein negatives long oder long, das den Bereich eines unsigned int überschreitet und in diesem Fall keine Ausnahme auslöst!

0

Sie können es einfach zu gieße einem int und tun, was Sie tun, dreht int s in Arrays, wie folgt aus: (nicht getestet)

public static byte[] getUnsignedInt(long value) 
{ 
    byte[] bytes = new byte[4]; 
    ByteBuffer.wrap(bytes).putInt((int)value); 
    return bytes; 
} 

Natürlich, wenn Sie diese Dinge in ein setzen sind ByteBuffer Wie auch immer, Sie könnten das auch direkt tun.

Die "Bedeutung" oder "Interpretation" des oberen Bits ist irrelevant, wenn Sie es nur speichern. Zum Beispiel würde 4294967295 als -1 interpretiert, aber es ist wirklich die gleiche Zahl: 0xFFFFFFFF in hexadezimal, so dass Sie das Byte-Array { 0xFF, 0xFF, 0xFF, 0xFF } erhalten.

es rückgängig zu machen, können Sie so etwas tun könnte (nicht getestet)

public static long toUnsignedInt(byte[] bytes) 
{ 
    ByteBuffer buffer = ByteBuffer.allocate(4).put(bytes); 
    buffer.position(0); 
    return buffer.getInt() & 0xFFFFFFFFL; 
} 
+0

Das funktioniert nicht, weil int einen Maximalwert von 2147483647 hat, während unsigned ints einen maximalen Wert von mehr hat als das Doppelte. Wird die long-Taste bis int gedrückt, so wird alles über den maximalen Wert hinaus verloren. – user2887053

+0

@ user2887053 nein, tut es nicht. Das "int" wird negativ sein, aber das hat keine Konsequenzen. – harold

1

Eine Antwort ohne die Objekterstellung und Array Kopieren der akzeptierte Antwort ... Es ist einfach, sich w/Shift-Operationen zu tun . Siehe:

import java.io.*; 

public class TestUINT32 { 

    public static void writeLongAsUINT32(long value, OutputStream os) throws IOException { 
    for (int i=0; i<4; ++i) { 
     os.write((byte) value); 
     value = value >> 8; 
    } 
    } 

    public static void main(String[] args) throws IOException { 
    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    long value = 0xFFEEDDBB; 
    writeLongAsUINT32(value, os); 
    byte[] ba = os.toByteArray(); 
    for (int i=ba.length; i>0; --i) { 
     System.out.print(String.format("%02X", ba[i-1])); 
    } 
    System.out.println(); 
    } 

} 

Beispiel laufen:

$ java TestUINT32 
FFEEDDBB