Skip to content

Instantly share code, notes, and snippets.

@drmalex07
Last active May 1, 2024 21:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drmalex07/9008c611ffde6cb2ef3a2db8668bc251 to your computer and use it in GitHub Desktop.
Save drmalex07/9008c611ffde6cb2ef3a2db8668bc251 to your computer and use it in GitHub Desktop.
Convert a UUID to an unsigned BigInteger #java #UUID #BigInteger
public static final BigInteger B = BigInteger.ONE.shiftLeft(64); // 2^64
public static final BigInteger L = BigInteger.valueOf(Long.MAX_VALUE);
public static BigInteger convertToBigInteger(UUID id)
{
BigInteger lo = BigInteger.valueOf(id.getLeastSignificantBits());
BigInteger hi = BigInteger.valueOf(id.getMostSignificantBits());
// If any of lo/hi parts is negative interpret as unsigned
if (hi.signum() < 0)
hi = hi.add(B);
if (lo.signum() < 0)
lo = lo.add(B);
return lo.add(hi.multiply(B));
}
public static UUID convertFromBigInteger(BigInteger x)
{
BigInteger[] parts = x.divideAndRemainder(B);
BigInteger hi = parts[0];
BigInteger lo = parts[1];
if (L.compareTo(lo) < 0)
lo = lo.subtract(B);
if (L.compareTo(hi) < 0)
hi = hi.subtract(B);
return new UUID(hi.longValueExact(), lo.longValueExact());
}
@vtherli
Copy link

vtherli commented Aug 5, 2018

Will this be unique like UUID?

@drmalex07
Copy link
Author

Since there is no loss of information, it will be as unique as the original UUID code.

@kmbotts
Copy link

kmbotts commented Dec 1, 2020

This works too. the hexidecimal conversion will always return an unsigned number

UUID uuid = UUID.randomUUID();
BigInteger uuidAsBigInteger = new BigInteger(uuid.toString().replace("-", ""), 16);

Edit: has nothing to do with hexdecimal converstion, just the default for that constructor from what I can read into the implementation.

@aasaru
Copy link

aasaru commented Jan 25, 2021

And one string based option for converting back:

    public static UUID convertFromBigInteger(BigInteger bigInteger) {
        String bigIntegerAsHex = bigInteger.toString(16);
        String leftPadded = org.apache.commons.lang3.StringUtils.leftPad(bigIntegerAsHex, 32, "0");
        String withDashes = leftPadded.replaceAll("^(.{8})(.{4})(.{4})(.{4})(.{12})$", "$1-$2-$3-$4-$5");
        return UUID.fromString(withDashes);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment