如何将字节数组转换为其数值(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 包的一部分提供的Buffers 来执行转换。

这里,源 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 方法。


虽然它可能不适用于这种情况,但 Buffers 的美妙之处在于查看具有多个值的数组。

例如,如果我们有一个 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] &amp; 0xffL) &lt;&lt; (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)?的主要内容,如果未能解决你的问题,请参考以下文章

如何把一个byte数组的数字转换成int

将字节数组转换为密钥

将对象数组转换为其原始类型的数组

如何在Java中将二维布尔数组转换为一维字节数组?

在labview中如何将16进制字符串数组转化为十进制数值数组?

java将字节数组转换成string