keysmith (keysmith v0.6.1)

View Source

Library for generating unique IDs.

KeySmith is a library for generating unique IDs. It supports two types of IDs:

  • UUID (RFC-9562)
    • The 'nil' uuid (00000000-0000-0000-0000-000000000000)
    • The 'max' uuid (ffffffff-ffff-ffff-ffff-ffffffffffff)
    • Version 4 (random)
    • Version 7 (time-based and random)
  • TypeID (specification)
    • TypeID's embed a UUID v7 by default, but can be customized with any supported UUID version

Summary

Types

An atom representing the type of ID

A generated TypeID

A TypeID 'type' prefix

An Erlang representation of a TypeID

A generated UUID value

UUID in raw binary format

UUID output format

UUID in hex format with dashes

UUID in hex format without dashes

An Erlang representation of a UUID

The 'max' uuid (ffffffff-ffff-ffff-ffff-ffffffffffff)

The 'nil' uuid (00000000-0000-0000-0000-000000000000)

A 12-bit random bitstring used in UUID generation

A 48-bit random bitstring used in UUID generation

A 62-bit random bitstring used in UUID generation

A shorthand for a UUID specification

UUID version 4 shorthand (with optional random components)

UUID version 7 shorthand (with optional timestamp and random components)

An UUID specification

UUID version 4 shorthand (with optional random components)

UUID version 7 (with optional timestamp and random components)

UNIX timestamp in millisecond resolution.

A full UUID specification

Functions

Parse an ID into its components.

Create a TypeID for the specified type prefix.

Generate a type ID for the specified type and UUID format. The UUID format can be any format supported by uuid/2.

Generate a UUID in the specified format.

Types

id()

-type id() :: uuid | type_id.

An atom representing the type of ID

time_unit()

-type time_unit() :: millisecond.

type_id()

-type type_id() :: binary().

A generated TypeID

type_id_prefix()

-type type_id_prefix() :: atom().

A TypeID 'type' prefix

type_id_spec()

-type type_id_spec() :: {type_id, type_id_prefix(), uuid_spec()}.

An Erlang representation of a TypeID

uuid()

-type uuid() :: uuid_binary() | uuid_hex() | uuid_hex_nodash().

A generated UUID value

uuid_binary()

-type uuid_binary() :: <<_:128>>.

UUID in raw binary format

uuid_format()

-type uuid_format() :: binary | bytes | hex | hex_nodash.

UUID output format

uuid_hex()

-type uuid_hex() :: <<_:288>>.

UUID in hex format with dashes

uuid_hex_nodash()

-type uuid_hex_nodash() :: <<_:256>>.

UUID in hex format without dashes

uuid_map()

-type uuid_map() ::
          #{var => rfc | {reserved, ncs | microsoft | future},
            ver => 0..15,
            val => uuid_value() | uuid_nil() | uuid_max(),
            bin => uuid_binary(),
            hex => uuid_hex()}.

An Erlang representation of a UUID

uuid_max()

-type uuid_max() :: max.

The 'max' uuid (ffffffff-ffff-ffff-ffff-ffffffffffff)

uuid_nil()

-type uuid_nil() :: nil.

The 'nil' uuid (00000000-0000-0000-0000-000000000000)

uuid_rand_12()

-type uuid_rand_12() :: <<_:12>>.

A 12-bit random bitstring used in UUID generation

uuid_rand_48()

-type uuid_rand_48() :: <<_:48>>.

A 48-bit random bitstring used in UUID generation

uuid_rand_62()

-type uuid_rand_62() :: <<_:62>>.

A 62-bit random bitstring used in UUID generation

uuid_short()

-type uuid_short() :: uuid_nil() | uuid_max() | uuid_short_v4() | uuid_short_v7().

A shorthand for a UUID specification

uuid_short_v4()

-type uuid_short_v4() :: 4 | {4, uuid_rand_48(), uuid_rand_12(), uuid_rand_62()}.

UUID version 4 shorthand (with optional random components)

uuid_short_v7()

-type uuid_short_v7() ::
          7 | {7, uuid_v7_unix_ts_ms()} | {7, uuid_v7_unix_ts_ms(), uuid_rand_12(), uuid_rand_62()}.

UUID version 7 shorthand (with optional timestamp and random components)

uuid_spec()

-type uuid_spec() :: uuid_short() | uuid_map().

An UUID specification

uuid_v4()

-type uuid_v4() :: #{rand_a => uuid_rand_48(), rand_b => uuid_rand_12(), rand_c => uuid_rand_62()}.

UUID version 4 shorthand (with optional random components)

uuid_v7()

-type uuid_v7() ::
          #{unix_ts => uuid_v7_unix_ts_ms(), rand_a => uuid_rand_12(), rand_b => uuid_rand_62()}.

UUID version 7 (with optional timestamp and random components)

uuid_v7_unix_ts_ms()

-type uuid_v7_unix_ts_ms() :: non_neg_integer() | {time_unit(), non_neg_integer()}.

UNIX timestamp in millisecond resolution.

(Tagged) timestamp value as generated from erlang:system_time(millisecond).

uuid_value()

-type uuid_value() :: uuid_v4() | uuid_v7().

A full UUID specification

Functions

parse/2

-spec parse(Format :: uuid, UUID :: uuid()) -> uuid_map();
           (Format :: type_id, TypeID :: type_id()) -> type_id_spec().

Parse an ID into its components.

Format can be one of uuid or type_id (id_type()).

  • uuid

    UUID will get decoded automatically based on their encoded type. The supported types are listed in the uuid/2 documentation. Only the full format of the UUID tuples can be returned by this function.

    Example

    1> UUIDv7 = keysmith:uuid({7, 123}).
    <<"00000000-007b-7dec-9675-e4c52b8138cc">>
    2> keysmith:parse(uuid, UUIDv7).
    #{var => rfc,
      ver => 7,
      bin => <<0,0,0,0,0,123,125,236,150,117,228,197,43,129,56,204>>,
      hex => <<"00000000-007b-7dec-9675-e4c52b8138cc">>,
      val =>
          #{rand_a => <<222,12:4>>,
            rand_b => <<89,215,147,20,174,4,227,12:6>>,
            unix_ts => {millisecond,123}}}
  • type_id

    A TypeID will get decoded to a tuple of the type and the UUID format. The type must exist as atom for this fuction to return succesfully (it uses binary_to_existing_atom/1 internally).

    The UUID suffix format must be in lowercase Crockfords's base32 encoding, otherwise an error will be thrown.

    Example

    1> TypeID = keysmith:type_id(my_type).
    <<"my_type_01j9p5p9wpf5asad1kvdww0gtd">>
    2> keysmith:parse(type_id, TypeID).
    {type_id,my_type,
             #{var => rfc,
               ver => 7,
               bin => <<1,146,108,91,39,150,121,85,149,52,51,219,121,192,67,77>>,
               hex => <<"01926c5b-2796-7955-9534-33db79c0434d">>,
               val =>
                   #{rand_a => <<149,5:4>>,
                     rand_b => <<84,208,207,109,231,1,13,13:6>>,
                     unix_ts => {millisecond,1728394766230}}}}

Errors

This fuction raises the following exceptions:

  • {invalid_id, type_id, ID} if a TypeID is parsed and is not a valid TypeID:
    • The type is not decodable into an existing atom
    • The UUID suffix not being a 26-byte lowercase Crockfords's base32 string
  • {invalid_id, uuid, ID} if a UUID is parsed and the ID is not a valid UUID, or if a TypeID contains a UUID suffix that is not a valid UUID:
    • The UUID not being a valid hexadecimal 36-byte UUID (with dashes)
    • The UUID not being a valid hexadecimal 32-byte UUID (without dashes)
    • The UUID not being a raw binary UUID of 128 bits
  • {invalid_format, Format} if the format is not supported.

type_id(Type)

-spec type_id(Type :: type_id_prefix()) -> TypeID :: type_id().

Create a TypeID for the specified type prefix.

This creates a TypeID with the specified type prefix and a UUID version 7 suffix including the current Unix system time in milliseconds.

Example

1> keysmith:type_id(my_type).
<<"my_type_01j8j55ywkesavxf5avszv4jv1">>

Equivalent to type_id(Type, v7).

type_id(Type, UUID)

-spec type_id(Type :: type_id_prefix(), UUID :: uuid_spec()) -> TypeID :: type_id().

Generate a type ID for the specified type and UUID format. The UUID format can be any format supported by uuid/2.

TypeIDs are encoded with a lowercase version of Crockford's base32 encoding.

Example

1> keysmith:type_id(my_type, {4, <<0:48>>, <<0:12>>, <<0:62>>}).
<<"my_type_00000000008008000000000000">>

uuid(Version)

-spec uuid(Version :: uuid_spec()) -> UUID :: uuid().

Equivalent to uuid(Type, hex).

uuid(Type, Format)

-spec uuid(Type :: uuid_spec(), Format :: uuid_format()) -> UUID :: uuid().

Generate a UUID in the specified format.

The following types are supported:

  • 4 - Random UUID v4.
  • {4, RandA, RandB, RandC} - UUID v4 with set random parts.
  • 7 - UUID v7 with the current system timestamp and a random component.
  • {7, TS} - UUID v7 with a set timestamp and a random component.
  • {7, TS, RandB, RandC} - UUID v7 with a set timestamp and set random components.

The following formats are supported:

  • bytes / binary - UUID as a raw 16 byte (128 bit) binary.
  • hex - UUID as a hexadecimal lowercase string with dashes.
  • hex_nodash - UUID as a hexadecimal lowercise string without dashes.

If custom random parts are provided, they must be bitstrings of exactly 48, 12, and 62 bits respectively (for example assuming each variable contains an integer, the binary syntax would be <<RandA:48>>, <<RandB:12>>, and <<RandC:62>>).

Errors

This fuction raises the following exceptions:

  • error:{invalid_uuid_spec, Spec} when an unsupported or invalid specification is specified.
  • error:{invalid_uuid_format, Format} when an unsupported or invalid format is specified.

Example

1> keysmith:uuid(4).
<<"38f18026-c2ee-4b5b-a8f7-439c33fb2a7a">>
2> keysmith:uuid(7).
<<"019228d7-b720-7484-ab83-25332e9b0a33">>