簡體   English   中英

在 Java 中將字節數組轉換為整數,反之亦然

[英]Convert a byte array to integer in Java and vice versa

我想在 Java 中將一些數據存儲到字節數組中。 基本上只是每個數字最多可以占用 2 個字節的數字。

我想知道如何將整數轉換為 2 字節長的字節數組,反之亦然。 我在谷歌上找到了很多解決方案,但大多數都沒有解釋代碼中發生的事情。 有很多變化的東西我不太明白,所以我希望得到一個基本的解釋。

使用java.nio命名空間中的java.nio ,特別是ByteBuffer 它可以為您完成所有工作。

byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1

ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }
byte[] toByteArray(int value) {
     return  ByteBuffer.allocate(4).putInt(value).array();
}

byte[] toByteArray(int value) {
    return new byte[] { 
        (byte)(value >> 24),
        (byte)(value >> 16),
        (byte)(value >> 8),
        (byte)value };
}

int fromByteArray(byte[] bytes) {
     return ByteBuffer.wrap(bytes).getInt();
}
// packing an array of 4 bytes to an int, big endian, minimal parentheses
// operator precedence: <<, &, | 
// when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right
int fromByteArray(byte[] bytes) {
     return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}

// packing an array of 4 bytes to an int, big endian, clean code
int fromByteArray(byte[] bytes) {
     return ((bytes[0] & 0xFF) << 24) | 
            ((bytes[1] & 0xFF) << 16) | 
            ((bytes[2] & 0xFF) << 8 ) | 
            ((bytes[3] & 0xFF) << 0 );
}

將有符號字節打包為 int 時,由於算術提升規則(在 JLS,轉換和提升中描述),每個字節都需要被屏蔽,因為它被符號擴展到 32 位(而不是零擴展)。

Joshua Bloch 和 Neal Gafter 在 Java Puzzlers(“A Big Delight in Every Byte”)中描述了一個與此相關的有趣謎題。 將字節值與 int 值進行比較時,該字節被符號擴展為 int,然后將此值與另一個 int 進行比較

byte[] bytes = (…)
if (bytes[0] == 0xFF) {
   // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255
}

請注意,除了 char 是 16 位無符號整數類型之外,所有數字類型都在 Java 中簽名。

您還可以將 BigInteger 用於可變長度字節。 您可以根據需要將其轉換為 long、int 或 short。

new BigInteger(bytes).intValue();

或表示極性:

new BigInteger(1, bytes).intValue();

要取回字節,只需:

new BigInteger(bytes).toByteArray()

一個基本的實現是這樣的:

public class Test {
    public static void main(String[] args) {
        int[] input = new int[] { 0x1234, 0x5678, 0x9abc };
        byte[] output = new byte[input.length * 2];

        for (int i = 0, j = 0; i < input.length; i++, j+=2) {
            output[j] = (byte)(input[i] & 0xff);
            output[j+1] = (byte)((input[i] >> 8) & 0xff);
        }

        for (int i = 0; i < output.length; i++)
            System.out.format("%02x\n",output[i]);
    }
}

為了理解你可以閱讀這篇WP文章: http : //en.wikipedia.org/wiki/Endianness

上面的源代碼將輸出34 12 78 56 bc 9a 前 2 個字節( 34 12 )表示第一個整數,依此類推。上述源代碼以小端格式對整數進行編碼。

/** length should be less than 4 (for int) **/
public long byteToInt(byte[] bytes, int length) {
        int val = 0;
        if(length>4) throw new RuntimeException("Too big to fit in int");
        for (int i = 0; i < length; i++) {
            val=val<<8;
            val=val|(bytes[i] & 0xFF);
        }
        return val;
    }

通常,番石榴有您需要的東西。

從字節數組到 int: Ints.fromBytesArray , doc here

從 int 到 byte 數組: Ints.toByteArray ,文檔在這里

有人要求他們必須從位讀取,假設您必須僅從 3 位讀取,但您需要有符號整數,然后使用以下內容:

data is of type: java.util.BitSet

new BigInteger(data.toByteArray).intValue() << 32 - 3 >> 32 - 3

幻數3可以替換為您使用的位數(而不是字節數)

我認為這是轉換為 int 的最佳模式

   public int ByteToint(Byte B){
        String comb;
        int out=0;
        comb=B+"";
        salida= Integer.parseInt(comb);
        out=out+128;
        return out;
    }

首先將字節轉換為字符串

comb=B+"";

下一步是轉換為 int

out= Integer.parseInt(comb);

但是由於這個原因,字節的范圍為 -128 到 127,我認為最好使用范圍 0 到 255,你只需要這樣做:

out=out+256;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM