我正在写入具有uint32的存储格式,其最大允许值为" 4294967295"。
当然,Java中的整数不到#34; 2147483647"的一半。所以在内部,我必须使用Long或Guava的UnsignedInteger。
要写入此格式,字节数组长度需要为4,这对于Integer来说很合适,但将Long转换为字节数组需要一个长度为8的数组。
如何转换表示最大值" 4294967295"的Long或UnsignedInteger?作为一个4字节的数组?
答案 0 :(得分:3)
只需将其转换为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();
}
请注意,此方法可以使用超出unsigned int范围的负long或long,并且在这种情况下不会抛出异常!
答案 1 :(得分:1)
没有创建对象并对所接受的答案进行数组复制的答案......使用移位操作很容易做到。参见:
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
答案 2 :(得分:0)
您可以将其转换为int
并执行任何操作,将int
转换为数组,例如:(未经测试)
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;
}