README.md

# UUIDv8

BEAM library for generating UUID versions 1, 4, 6, 7 and 8.

Core Erlang libraries have functions for secure random data, unique integer 
sequences, and distributed node names.

Given these functions are so simple it is possible to just copy/paste the few
required into your code rather than including this library.

## Versions & Formats

There are 122 bits of usable data with 4 bits specifying the version and 2 the variant.

Which is normally formatted as:

    aaaaaaaa-aaaa-vbbb-cccc-dddddddddddd

where v is the version.

This table shows the bit layout output by each UUID generator in the library:

| generator | a        | v | b        | c        | d        |
| --------- | -------- | - | -------- | -------- | -------- |
| random_v8 | random   | 8 | random   | random   | random   |
|           |          |   |          |          |          |
|           |          |   |          |          |          |
| uuid_v7   | time     | 7 | sequence | random   | random   |
| uuid_v6   | time     | 6 | time     | sequence | node     |
| uuid_v4   | random   | 4 | random   | random   | random   |
| uuid_v1   | time low | 1 | time     | sequence | node     |



## Build

    $ rebar3 compile

## Test

    $ rebar3 eunit

## Erlang

Generate a hexadecimal tagged UUID:

```erlang
UUID = binary:encode_hex(uuidv8:node_tagged_v8(16#81D))
```

## Elixir integration

Generate a hexadecimal UUID from Elixir:

```elixir
defmodule YourApp.Identifiers do
    import Base, only: [encode16: 1]
    defdelegate random_v8, to: :uuidv8

    def random_uuidv8_hex, do: encode16(random_v8())
end
```

## Gleam integration

Generate a hexadecimal UUID from Gleam:

```gleam
import gleam/bit_array.{base16_encode}

pub fn random_uuid_v8_hex() -> String {
    base16_encode(random_v8())
}

@external(erlang, "uuidv8", "random_v8")
pub fn random_v8() -> BitArray
```

# UUID Versions

## UUID v1

[UUIDv1][v1] is a time-based UUID featuring a 60-bit timestamp represented by 
Coordinated Universal Time (UTC) as a count of 100-nanosecond intervals 
since 1582-10-15T00:00:00.00Z. Not recommended, surpassed by [UUIDv6][v6].

Contains:
* 60 bits of timestamp (low bits first, not good for database indexing)
* 14 bits of monotonic integers
* 48 bits of node identifier (hash of BEAM node name)

```bash
./gen_uuid v1 4 
9cc76c44-0e93-11f1-8001-d6659d452b34
9cc839cb-0e93-11f1-8002-d6659d452b34
9cc83f02-0e93-11f1-8003-d6659d452b34
9cc84400-0e93-11f1-8004-d6659d452b34
```

## UUID v4

[UUIDv4][v4] is meant for generating UUIDs from truly random or pseudorandom numbers.

Contains 122 bits of strong random bytes:

```bash
$ ./gen_uuid v4 2
9f33f7a7-b066-476c-8b82-6f9968d59e62
c30f8a24-96e7-4a56-8c46-f62488ae81fe
```

## UUID v6

[UUIDv6][v6] is a field-compatible version of UUIDv1, reordered for improved 
DB locality. It is expected that UUIDv6 will primarily be implemented in 
contexts where UUIDv1 is used. Systems that do not involve legacy UUIDv1 
SHOULD use UUIDv7 instead.

Contains:
* 60 bits of Gregorian monotonic timestamp (in microseconds)
* 14 bits of monotonic integers
* 48 bits of node identifier (hash of BEAM node name)

```bash
$ ./gen_uuid v6 16384
0e328083-bf10-65ff-8001-d6659d452b34
0e328083-bf11-6901-8002-d6659d452b34
0e328083-bf11-6947-8003-d6659d452b34
0e328083-bf11-69ad-8004-d6659d452b34
...
0e328083-e406-6968-bffd-d6659d452b34
0e328083-e406-6973-bffe-d6659d452b34
0e328083-e406-697e-bfff-d6659d452b34
0e328083-e406-6989-8000-d6659d452b34
```

## UUID v7

[UUIDv7][v7] features a time-ordered value field derived from the widely implemented and well-known Unix Epoch timestamp source, the number of milliseconds since midnight 1 Jan 1970 UTC, leap seconds excluded. Generally, UUIDv7 has improved entropy characteristics over UUIDv1.

Contains:
* 48 bits of monotonic UNIX timestamp
* 12 bits of monotonic unique integers
* 62 bits of strong random data

```bash
$ ./gen_uuid v7 4096
019c67db-6ef1-7001-abf4-7a13df92d388
019c67db-6ef1-7002-a744-5f1591749501
019c67db-6ef1-7003-b986-3d3035f199fa
...
019c67db-f691-7ffe-9335-b46d9c4cb789
019c67db-f691-7fff-af33-7e92e4441864
019c67db-f691-7000-b45c-31a2fce9aa3d
```

## UUID v8

[UUIDv8][v8] provides a format for experimental or vendor-specific use cases

### UUID v8 random

Contains 122 bits of strong random bytes:

```bash
$ ./gen_uuid v8 2          
578b3a94-6484-8f9d-8ae3-5337bd88ebfb
018a4bd7-a5f6-88a1-95c4-1bfdaec4c8a1
```

### UUID v8 tagged

Contains:
* 48 bits of monotonic UNIX timestamp
* 12 bits of tag (3 hexadecimal digits)
* 62 bits of monotonic unique integers

```bash
$ ./gen_uuid v8 "0xD0C" 65536
019c6845-ba73-8d0c-b800-000000000025
019c6845-ba73-8d0c-b800-000000000045
019c6845-ba73-8d0c-b800-000000000065
019c6845-ba73-8d0c-b800-000000000085     
...     
019c6845-ba80-8d0c-b800-000000001fa5
019c6845-ba80-8d0c-b800-000000001fc5
019c6845-ba80-8d0c-b800-000000001fe5
019c6845-ba80-8d0c-b800-000000002005
...
019c6849-dd85-8d0c-b800-000000200401
019c6849-dd85-8d0c-b800-000000200421
019c6849-dd85-8d0c-b800-000000200441
019c6849-dd85-8d0c-b800-000000200461
```

### UUID v8 node tagged

Contains:
* 48 bits of monotonic UNIX timestamp
* 12 bits of tag (3 hexadecimal digits)
* 32 bits of node identifier (hash of BEAM node name)
* 30 bits of monotonic unique integers

```bash
$ ./gen_uuid v8node "0xD8D" 65536 | tail
019c7c93-117d-8d8d-817c-a96500000466
019c7c93-117d-8d8d-817c-a96500000486
019c7c93-117d-8d8d-817c-a965000004a6
019c7c93-117d-8d8d-817c-a965000004c6
...
019c7c93-21ec-8d8d-817c-a965001e65a2
019c7c93-21ec-8d8d-817c-a965001e65c2
019c7c93-21ec-8d8d-817c-a965001e65e2
019c7c93-21ec-8d8d-817c-a965001e6602
```

[v1]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-1
[v4]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-4
[v6]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-6
[v7]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7
[v8]: https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-8