UUIDs in 22 characters

unimplemented! (keyword){:type "keyword", :affiliated {}, :key "DATE", :value "[2025-09-16 Tue 06:18]", :position {:start {:line 6, :column 1, :offset 128}, :end {:line 7, :column 1, :offset 159}}}

I'm currently working on publishing my Org-roam notes to Deertopia's webpage. The URL for a given note is deertopia.net/id/«UUID» — Org-roam's default method of identifying a node is a 36-character UUID. These URLs are a bit unwieldy, so I'd like to attack the redundancies and compression opportunities of UUIDs.

The hyphens

The most obvious point to attack is the hyphens used in the human-readable representations of UUIDs. We can parse that string into the underlying 128-bit word and encode it some other way for an easy four-character trim.

The character set

UUID digits are merely hexadecimal, and it's pathetic!!! We can encode that aforementioned 128-bit word in base-64 to reduce the string length by roughly â…”.

  (import (java.util UUID Base64)
          (java.nio ByteBuffer))

  (defn uuid->bytes [uuid]
    (.array (doto (ByteBuffer/wrap (byte-array 16))
              (.putLong (.getMostSignificantBits uuid))
              (.putLong (.getLeastSignificantBits uuid)))))

  (defn bytes->uuid [bytes]
    (let [bb (ByteBuffer/wrap bytes)
          high (.getLong bb)
          low (.getLong bb)]
      (UUID. high low)))

  (defn uuid->base64 [uuid]
    (let [encoder (.withoutPadding (Base64/getUrlEncoder))]
      (.encodeToString encoder (uuid->bytes uuid))))

  (defn base64->uuid [base64]
    (let [decoder (Base64/getUrlDecoder)]
      (bytes->uuid (.decode decoder base64))))

  (let [uuid #uuid "f9eab66e-7773-4b87-b854-0bfc8f563809"
        base64 (uuid->base64 uuid)
        round-tripped (base64->uuid base64)]
    {:uuid uuid, :base64 base64, :round-tripped round-tripped})

The redundancies

Yet to be implemented. UUIDs contain fixed bits for things like the version number. If we ensure we only deal with a single type of UUID, we can safely remove it.