我对这两个功能有些困难:byteArrayToInt
和intToByteArray
.
问题是,如果我使用一个来到另一个并且结果到达前者,结果会有所不同,您可以从下面的示例中看到.
我找不到代码中的错误.任何想法都非常受欢迎.谢谢.
public static void main(String[] args)
{
int a = 123;
byte[] aBytes = intToByteArray(a);
int a2 = byteArrayToInt(aBytes);
System.out.println(a); // prints '123'
System.out.println(aBytes); // prints '[B@459189e1'
System.out.println(a2); // prints '2063597568
System.out.println(intToByteArray(a2)); // prints '[B@459189e1'
}
public static int byteArrayToInt(byte[] b)
{
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i] & 0x000000FF) << shift;
}
return value;
}
public static byte[] intToByteArray(int a)
{
byte[] ret = new byte[4];
ret[0] = (byte) (a & 0xFF);
ret[1] = (byte) ((a >> 8) & 0xFF);
ret[2] = (byte) ((a >> 16) & 0xFF);
ret[3] = (byte) ((a >> 24) & 0xFF);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
Yan*_*hon 56
你的方法应该是(类似的)
public static int byteArrayToInt(byte[] b)
{
return b[3] & 0xFF |
(b[2] & 0xFF) << 8 |
(b[1] & 0xFF) << 16 |
(b[0] & 0xFF) << 24;
}
public static byte[] intToByteArray(int a)
{
return new byte[] {
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) (a & 0xFF)
};
}
Run Code Online (Sandbox Code Playgroud)
使用以下代码测试了这些方法:
Random rand = new Random(System.currentTimeMillis());
byte[] b;
int a, v;
for (int i=0; i<10000000; i++) {
a = rand.nextInt();
b = intToByteArray(a);
v = byteArrayToInt(b);
if (a != v) {
System.out.println("ERR! " + a + " != " + Arrays.toString(b) + " != " + v);
}
}
System.out.println("Done!");
Run Code Online (Sandbox Code Playgroud)
aro*_*oth 42
您正在交换两种方法之间的字节顺序.您已将intToByteArray(int a)
低位指定为ret[0]
,但随后byteArrayToInt(byte[] b)
分配b[0]
给结果的高位.您需要反转其中一个,例如:
public static byte[] intToByteArray(int a)
{
byte[] ret = new byte[4];
ret[3] = (byte) (a & 0xFF);
ret[2] = (byte) ((a >> 8) & 0xFF);
ret[1] = (byte) ((a >> 16) & 0xFF);
ret[0] = (byte) ((a >> 24) & 0xFF);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
Maa*_*wes 41
这是很多工作:
public static int byteArrayToLeInt(byte[] b) {
final ByteBuffer bb = ByteBuffer.wrap(b);
bb.order(ByteOrder.LITTLE_ENDIAN);
return bb.getInt();
}
public static byte[] leIntToByteArray(int i) {
final ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(i);
return bb.array();
}
Run Code Online (Sandbox Code Playgroud)
此方法使用包中的Java ByteBuffer
和ByteOrder
功能java.nio
.在需要可读性的情况下,此代码应该是首选.它也应该很容易记住.
我在这里显示了Little Endian字节顺序.要创建Big Endian版本,您可以简单地省略呼叫order(ByteOrder)
.
在性能优先于可读性的代码中(大约快10倍):
public static int byteArrayToLeInt(byte[] encodedValue) {
int value = (encodedValue[3] << (Byte.SIZE * 3));
value |= (encodedValue[2] & 0xFF) << (Byte.SIZE * 2);
value |= (encodedValue[1] & 0xFF) << (Byte.SIZE * 1);
value |= (encodedValue[0] & 0xFF);
return value;
}
public static byte[] leIntToByteArray(int value) {
byte[] encodedValue = new byte[Integer.SIZE / Byte.SIZE];
encodedValue[3] = (byte) (value >> Byte.SIZE * 3);
encodedValue[2] = (byte) (value >> Byte.SIZE * 2);
encodedValue[1] = (byte) (value >> Byte.SIZE);
encodedValue[0] = (byte) value;
return encodedValue;
}
Run Code Online (Sandbox Code Playgroud)
只需将字节数组索引反转为从0到3的计数,即可创建此代码的Big Endian版本.
笔记:
Integer.BYTES
常量,这比常量更简洁Integer.SIZE / Byte.SIZE
.Jam*_*oms 21
您还可以将BigInteger用于可变长度字节.您可以将其转换为Long,Integer或Short,以满足您的需求.
new BigInteger(bytes).intValue();
Run Code Online (Sandbox Code Playgroud)
或表示极性:
new BigInteger(1, bytes).intValue();
Run Code Online (Sandbox Code Playgroud)
要获取字节只是:
new BigInteger(bytes).toByteArray()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
136731 次 |
最近记录: |