Uuidm v0.9.9-2-g44893bd

Uuidm implements 128 bits universally unique identifiers version 3, 5 (named based with MD5, SHA-1 hashing), 4 (random based), 7 (time and random based) and 8 (custom) according according to RFC 9562.

See the quick start.

Library uuidm

Quick start

Random V4 UUIDs

The following uuid function generates V4 random UUIDs.

let uuid = Uuidm.v4_gen (Random.State.make_self_init ())
let () = print_endline (Uuidm.to_string (uuid ()))
let () = print_endline (Uuidm.to_string (uuid ()))

Make sure to read the warnings about random generators.

Name based V5 UUIDs

Name based V5 UUIDs can be used to generate urn:uuid URIs for atom feed entry IDs to minimize the chances of feed replays.

First generate a random V4 UUID for the feed. For example with the code of the previous section or with:

> uuidtrip
6228c5f9-7069-4519-9bf4-0b6e865f4c42

Store this UUID preciously and use it as your feed ID:

let feed_id ~feed_id = "urn:uuid:" ^ (Uuid.to_string feed_id)

For feed entry IDs, use the feed UUID as a V5 namespace and the immutable atom:published value of the entry as the data to hash:

let entry_id ~feed_id ~rfc3339_stamp =
    "urn:uuid:" ^ (Uuidm.to_string @@ Uuidm.v5 feed_id rfc3339_stamp)

This assumes that

  1. You do not publish two entries at exactly the same time. RFC 3339 has enough time granularity to ensure that.
  2. You do not change your publication dates. In atom they must in fact not change, updates to entries must be specified in atom:updated.
  3. If you store publication dates as a raw POSIX timestamp be careful to render them to RFC 3339 with a fixed time zone. Alternatively you can directly use the decimal representation of the timestamp as the data to hash.

Monotonic time based V7 UUIDs

In order to generate monotonic time based V7 UUIDs we need to:

let uuid_monotonic =
  let now_ms () = Int64.of_float (Unix.gettimeofday () *. 1000.) in
  Uuidm.v7_monotonic_gen ~now_ms (Random.State.make_self_init ())

let rec uuid () = match uuid_monotonic () with
| None -> (* Too many UUIDs generated in a ms *) Unix.sleepf 1e-3; uuid ()
| Some uuid -> uuid

let () = print_endline (Uuidm.to_string (uuid ()))
let () = print_endline (Uuidm.to_string (uuid ()))

Depending on your application Uuidm.v7_monotonic_gen may be a bit too simplistic, you can easily implement all sorts of other generation schemes by using Uuidm.v7 or Uuidm.v7_ns directly. Also, make sure to read the warnings about generators.