[英]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;
}
有人要求他们必须从位读取,假设您必须仅从 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.