如何将字节数组转换为其数值(Java)?
Posted
技术标签:
【中文标题】如何将字节数组转换为其数值(Java)?【英文标题】:How to convert a byte array to its numeric value (Java)? 【发布时间】:2010-11-04 20:01:29 【问题描述】:我有一个 8 字节数组,我想把它转换成对应的数值。
例如
byte[] by = new byte[8]; // the byte array is stored in 'by'
// CONVERSION OPERATION
// return the numeric value
我想要一个可以执行上述转换操作的方法。
【问题讨论】:
“数值”是什么意思?字节是表示二进制整数(长整数)还是浮点数(双精度)?它们是数字的字符串表示形式吗?还是另一种表现形式? 这很有帮助:***.com/questions/5399798/… 注意:TacB0sS 的链接是我真正想要的——前向和后向转换。new BigInteger(by).longValue()
【参考方案1】:
可以使用作为java.nio
包的一部分提供的Buffer
s 来执行转换。
这里,源 byte[]
数组的长度为 8,这是与 long
值对应的大小。
首先将byte[]
数组包裹在ByteBuffer
中,然后调用ByteBuffer.getLong
方法获取long
值:
ByteBuffer bb = ByteBuffer.wrap(new byte[] 0, 0, 0, 0, 0, 0, 0, 4);
long l = bb.getLong();
System.out.println(l);
结果
4
感谢 dfa 指出 cmets 中的 ByteBuffer.getLong
方法。
虽然它可能不适用于这种情况,但 Buffer
s 的美妙之处在于查看具有多个值的数组。
例如,如果我们有一个 8 字节数组,并且我们想将其视为两个 int
值,我们可以将 byte[]
数组包装在一个 ByteBuffer
中,它被视为一个 IntBuffer
和通过IntBuffer.get
获取值:
ByteBuffer bb = ByteBuffer.wrap(new byte[] 0, 0, 0, 1, 0, 0, 0, 4);
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);
System.out.println(i0);
System.out.println(i1);
结果:
1
4
【讨论】:
ByteBuffer.wrap(new byte[] 0, 0, 0, 1, 0, 0, 0, 4).getLong() 怎么样?此方法应读取下一个 8 字节并将它们转换为长 @dfa:感谢您指出这一点,它似乎确实有效——我将编辑答案。 :)【参考方案2】:假设第一个字节是最低有效字节:
long value = 0;
for (int i = 0; i < by.length; i++)
value += ((long) by[i] & 0xffL) << (8 * i);
第一个字节是最重要的,然后有点不同:
long value = 0;
for (int i = 0; i < by.length; i++)
value = (value << 8) + (by[i] & 0xff);
如果超过 8 个字节,请将 long 替换为 BigInteger。
感谢 Aaron Digulla 纠正我的错误。
【讨论】:
-1 字节是有符号值!并将 pow() 替换为 shift ( 移位运算符( @Mnementh :移位运算符( 如果其他人遇到我遇到的相同问题,在第一个示例中,必须将 by[i] 转换为 long,否则它仅适用于小于 2^32 的值。即value += ((long)by[i] & 0xffL) << (8 * i);
【参考方案3】:
如果这是一个8字节的数值,你可以试试:
BigInteger n = new BigInteger(byteArray);
如果这是一个 UTF-8 字符缓冲区,那么你可以尝试:
BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));
【讨论】:
如果它在第一个代码 sn-p 之后结束,或者如果它包含一些将字符串转换为“数值”的代码,我会投票支持这个答案。照原样,你答案的后半部分似乎不合逻辑。 不是我一开始的意思,我改变了答案【参考方案4】:简单来说,你可以使用或参考google提供的guava库,它提供了长数组和字节数组之间转换的实用方法。我的客户代码:
long content = 212000607777l;
byte[] numberByte = Longs.toByteArray(content);
logger.info(Longs.fromByteArray(numberByte));
【讨论】:
google.github.io/guava/releases/21.0/api/docs/com/google/common/…【参考方案5】:您还可以将 BigInteger 用于可变长度字节。您可以根据需要将其转换为 Long、Integer 或 Short。
new BigInteger(bytes).intValue();
或表示极性:
new BigInteger(1, bytes).intValue();
【讨论】:
【参考方案6】:所有原始类型到/从数组的完整 Java 转换器代码 http://www.daniweb.com/code/snippet216874.html
【讨论】:
【参考方案7】:数组中的每个单元格都被视为无符号整数:
private int unsignedIntFromByteArray(byte[] bytes)
int res = 0;
if (bytes == null)
return res;
for (int i=0;i<bytes.length;i++)
res = res | ((bytes[i] & 0xff) << i*8);
return res;
【讨论】:
请注意,我需要使用 0xFFL,否则当我打印 Long.toHexString(l) 时,从 int 0xFF 到 long 的转换设置了很多不正确的 1 位。 你需要使用 0xFFL 否则你会得到符号扩展。【参考方案8】:public static long byteArrayToLong(byte[] bytes)
return ((long) (bytes[0]) << 56)
+ (((long) bytes[1] & 0xFF) << 48)
+ ((long) (bytes[2] & 0xFF) << 40)
+ ((long) (bytes[3] & 0xFF) << 32)
+ ((long) (bytes[4] & 0xFF) << 24)
+ ((bytes[5] & 0xFF) << 16)
+ ((bytes[6] & 0xFF) << 8)
+ (bytes[7] & 0xFF);
将字节数组(long 为 8 字节)转换为 long
【讨论】:
【参考方案9】:您可以尝试使用此答案中的代码:https://***.com/a/68393576/7918717
它将字节解析为任意长度的有符号数。几个例子:
bytesToSignedNumber(false, 0xF1, 0x01, 0x04)
返回15794436
(3 个字节为 int)
bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x04)
返回-251592444
(4 个字节为 int)
bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04)
返回 -1080581331768770303
(9 个字节中的 8 个为 long)
【讨论】:
以上是关于如何将字节数组转换为其数值(Java)?的主要内容,如果未能解决你的问题,请参考以下文章