Question

What is the most time efficient way to create and Base32 encode a random UUID in Java? I would like to use Base32 encoding to store globally unique IDs that are usable in URLs.

Was it helpful?

Solution

Base32 still pads with the = character, so you'll need to do something with that if you really want to avoid URL escaping.

If you really want to avoid Base16, I recommend you use Base64 instead of Base32. If you want to use an RFC standard, try base64url. However, that standard also uses "=" for the trailing padding, so you need to escape that. It's substitutions are:

  • + -> -
  • / -> _
  • = -> =

Personally, I use a variant called Y64. It's substitutions are:

  • + -> .
  • / -> _
  • = -> -

It's not an RFC standard, but at least you don't have to worry about escaping the trailing "=".

Apache Commons Codec provides both Base64 and Base32. Here's an example with Base64 with the Y64 variant

To encode:

UUID uuid = UUID.randomUUID();
ByteBuffer uuidBuffer = ByteBuffer.allocate(16);
LongBuffer longBuffer = uuidBuffer.asLongBuffer();
longBuffer.put(uuid.getMostSignificantBits());
longBuffer.put(uuid.getLeastSignificantBits());
String encoded = new String(Base64.encode(uuidBuffer.array()), 
        Charset.forName("US-ASCII"));
encoded = encoded.replace('+', '.')
        .replace('/', '_')
        .replace('=', '-');

And decode:

String encoded; // from your request parameters or whatever
encoded = encoded.replace('.', '+')
        .replace('_', '/')
        .replace('-', '=');
ByteBuffer uuidBuffer = ByteBuffer.wrap(Base64.decode(
        encoded.getBytes(Charset.forName("US-ASCII"))));
LongBuffer longBuffer = uuidBuffer.asLongBuffer();
UUID uuid = new UUID(longBuffer.get(), longBuffer.get());

OTHER TIPS

I agreed with the discussion that Base64Url might be more suitable but I also see the benefit of generating unique value in Base32. It's case insensitive that is easier to handle if human is involved.

This is my code to convert UUID to Base32 using Guava's BaseEncoding.

    public static String toBase32(UUID uuid){
        ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());
        return BaseEncoding.base32().omitPadding().encode(bb.array());
    }

The codec Base32Codec can encode UUIDs efficiently to base-32.

// Returns a base-32 string
// uuid::: 01234567-89AB-4DEF-A123-456789ABCDEF
// base32: aerukz4jvng67ijdivtytk6n54
String string = Base32Codec.INSTANCE.encode(uuid);

There are codecs for other encodings in the same package of uuid-creator.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top