简体   繁体   English

在 Java 中将字节数组转换为整数,反之亦然

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

I want to store some data into byte arrays in Java.我想在 Java 中将一些数据存储到字节数组中。 Basically just numbers which can take up to 2 Bytes per number.基本上只是每个数字最多可以占用 2 个字节的数字。

I'd like to know how I can convert an integer into a 2 byte long byte array and vice versa.我想知道如何将整数转换为 2 字节长的字节数组,反之亦然。 I found a lot of solutions googling but most of them don't explain what happens in the code.我在谷歌上找到了很多解决方案,但大多数都没有解释代码中发生的事情。 There's a lot of shifting stuff I don't really understand so I would appreciate a basic explanation.有很多变化的东西我不太明白,所以我希望得到一个基本的解释。

Use the classes found in the java.nio namespace, in particular, the ByteBuffer .使用java.nio命名空间中的java.nio ,特别是ByteBuffer It can do all the work for you.它可以为您完成所有工作。

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

When packing signed bytes into an int, each byte needs to be masked off because it is sign-extended to 32 bits (rather than zero-extended) due to the arithmetic promotion rule (described in JLS, Conversions and Promotions).将有符号字节打包为 int 时,由于算术提升规则(在 JLS,转换和提升中描述),每个字节都需要被屏蔽,因为它被符号扩展到 32 位(而不是零扩展)。

There's an interesting puzzle related to this described in Java Puzzlers ("A Big Delight in Every Byte") by Joshua Bloch and Neal Gafter . Joshua Bloch 和 Neal Gafter 在 Java Puzzlers(“A Big Delight in Every Byte”)中描述了一个与此相关的有趣谜题。 When comparing a byte value to an int value, the byte is sign-extended to an int and then this value is compared to the other int将字节值与 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
}

Note that all numeric types are signed in Java with exception to char being a 16-bit unsigned integer type.请注意,除了 char 是 16 位无符号整数类型之外,所有数字类型都在 Java 中签名。

You can also use BigInteger for variable length bytes.您还可以将 BigInteger 用于可变长度字节。 You can convert it to long, int or short, whichever suits your needs.您可以根据需要将其转换为 long、int 或 short。

new BigInteger(bytes).intValue();

or to denote polarity:或表示极性:

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

To get bytes back just:要取回字节,只需:

new BigInteger(bytes).toByteArray()

A basic implementation would be something like this:一个基本的实现是这样的:

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

In order to understand things you can read this WP article: http://en.wikipedia.org/wiki/Endianness为了理解你可以阅读这篇WP文章: http : //en.wikipedia.org/wiki/Endianness

The above source code will output 34 12 78 56 bc 9a .上面的源代码将输出34 12 78 56 bc 9a The first 2 bytes ( 34 12 ) represent the first integer, etc. The above source code encodes integers in little endian format.前 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;
    }

As often, guava has what you need.通常,番石榴有您需要的东西。

To go from byte array to int: Ints.fromBytesArray , doc here从字节数组到 int: Ints.fromBytesArray , doc here

To go from int to byte array: Ints.toByteArray , doc here从 int 到 byte 数组: Ints.toByteArray ,文档在这里

Someone with a requirement where they have to read from bits, lets say you have to read from only 3 bits but you need signed integer then use following:有人要求他们必须从位读取,假设您必须仅从 3 位读取,但您需要有符号整数,然后使用以下内容:

data is of type: java.util.BitSet

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

The magic number 3 can be replaced with the number of bits (not bytes) you are using.幻数3可以替换为您使用的位数(而不是字节数)

i think this is a best mode to cast to int我认为这是转换为 int 的最佳模式

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

first comvert byte to String首先将字节转换为字符串

comb=B+"";

next step is comvert to a int下一步是转换为 int

out= Integer.parseInt(comb);

but byte is in rage of -128 to 127 for this reasone, i think is better use rage 0 to 255 and you only need to do this:但是由于这个原因,字节的范围为 -128 到 127,我认为最好使用范围 0 到 255,你只需要这样做:

out=out+256;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM