Search code examples
uuidbiginteger

BufferUnderflowException while converting UUID to/from BigInteger


public static BigInteger bigInteger(UUID uuid) {
    ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
    bb.putLong(uuid.getMostSignificantBits());
    bb.putLong(uuid.getLeastSignificantBits());
    return new BigInteger(bb.array());
}

public static UUID uuid(BigInteger value)  {
    byte[] bytes = value.toByteArray();
    ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
    Long high = byteBuffer.getLong();
    Long low = byteBuffer.getLong();
    return new UUID(high, low);
}

Why does the following test fails with java.nio.BufferUnderflowException:

@Test
public void testUuidBigInteger_underflow() {
    UUID uuidValue = UUID.fromString("ffe11491-04ab-4602-bd85-08716fb4d384");
    BigInteger bigIntegerValue = bigInteger(uuidValue);
    UUID uuidValue2 = uuid(bigIntegerValue);
    assertEquals(uuidValue, uuidValue2);
}

Solution

  • In between writing and reading from the ByteBuffer, you need to call the .flip() method - setting the limit of the buffer to the current position, and the position to 0 - i.e. as below:-

    public static BigInteger bigInteger(UUID uuid) {
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        bb.flip();
        return new BigInteger(bb.array());
    }