【问题标题】:Java uint32 (stored as long) to 4 byte arrayJava uint32(存储为long)到4字节数组
【发布时间】:2017-06-30 19:29:26
【问题描述】:

我正在写入具有 uint32 的存储格式,最大允许值为“4294967295”。

Java 中的整数当然是“2147483647”的一半。所以在内部,我必须使用 Long 或 Guava 的 UnsignedInteger。

要写入这种格式,字节数组长度需要为 4,正好适合 Integer,但是将 Long 转换为字节数组需要长度为 8 的数组。

如何将表示最大值“4294967295”的 Long 或 UnsignedInteger 转换为 4 字节数组?

【问题讨论】:

    标签: java byte uint32


    【解决方案1】:

    只需将其转换为 8 字节数组,然后只取最后 4 个字节:

     public static byte[] fromUnsignedInt(long value)
     {
         byte[] bytes = new byte[8];
         ByteBuffer.wrap(bytes).putLong(value);
    
         return Arrays.copyOfRange(bytes, 4, 8);
     }
    

    要扭转这种情况,您可以使用以下方法:

     public static long toUnsignedInt(byte[] bytes)
     {
         ByteBuffer buffer = ByteBuffer.allocate(8).put(new byte[]{0, 0, 0, 0}).put(bytes);
         buffer.position(0);
    
         return buffer.getLong();
     }
    

    请注意,此方法可以采用负长整数或超出无符号整数范围的长整数,并且在这种情况下不会抛出异常!

    【讨论】:

      【解决方案2】:

      您可以将其转换为 int 并执行将 ints 转换为数组的任何操作,例如:(未测试)

      public static byte[] getUnsignedInt(long value)
      {
          byte[] bytes = new byte[4];
          ByteBuffer.wrap(bytes).putInt((int)value);
          return bytes;
      }
      

      当然,如果你把这些东西放在ByteBuffer 中,你也可以直接这样做。

      如果你所做的一切都是为了存储它,那么最高位的“意义”或“解释”是无关紧要的。例如,4294967295 会被解释为 -1,但它实际上是同一个数字:十六进制的 0xFFFFFFFF,所以你会得到字节数组{ 0xFF, 0xFF, 0xFF, 0xFF }

      要扭转它,你可以做这样的事情(未测试)

      public static long toUnsignedInt(byte[] bytes)
      {
          ByteBuffer buffer = ByteBuffer.allocate(4).put(bytes);
          buffer.position(0);
          return buffer.getInt() & 0xFFFFFFFFL;
      }
      

      【讨论】:

      • 这不起作用,因为 int 的最大值为 2147483647,而 unsigned int 的最大值是该最大值的两倍多。将 long 向下转换为 int 会丢失超过最大 int 值的任何内容。
      • @user2887053 不,它没有。 int 将是负数,但这无关紧要。
      【解决方案3】:

      没有对象创建和已接受答案的数组复制的答案...使用移位操作很容易自己做。见:

      import java.io.*;
      
      public class TestUINT32 {
      
        public static void writeLongAsUINT32(long value, OutputStream os) throws IOException {
          for (int i=0; i<4; ++i) {
            os.write((byte) value);
            value = value >> 8;
          }
        }
      
        public static void main(String[] args) throws IOException {
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          long value = 0xFFEEDDBB;
          writeLongAsUINT32(value, os);
          byte[] ba = os.toByteArray();
          for (int i=ba.length; i>0; --i) {
            System.out.print(String.format("%02X", ba[i-1]));
          }
          System.out.println();
        }
      
      }
      

      示例运行:

      $ java TestUINT32 
      FFEEDDBB
      

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 2012-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多