【问题标题】:How to convert a byte array to its numeric value (Java)?如何将字节数组转换为其数值(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

我想要一个可以执行上述转换操作的方法。

【问题讨论】:

  • “数值”是什么意思?字节是表示二进制整数(长整数)还是浮点数(双精度)?它们是数字的字符串表示形式吗?还是另一种表现形式?
  • 注意:TacB0sS 的链接是我真正想要的——前向和后向转换。
  • new BigInteger(by).longValue()

标签: java algorithm bytearray numbers


【解决方案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));
【解决方案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://stackoverflow.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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-02
          • 1970-01-01
          • 2010-12-28
          • 1970-01-01
          • 2014-12-27
          • 2011-03-11
          • 1970-01-01
          相关资源
          最近更新 更多