
ULID: Universally Unique Lexicographically Sortable Identifier - im_dario
https://github.com/alizain/ulid
======
niftich
For what it's worth, the UUID RFC actually has a provision for using random
bits instead of the MAC address in a version 1 UUID [ref], which results in a
similar, but incompatible structure as to what's proposed here.

I'm not sure what this new, incompatible format buys over that one, other than
a different allocation of bits between the time and random fields.

[ref]
[https://tools.ietf.org/html/rfc4122#section-4.5](https://tools.ietf.org/html/rfc4122#section-4.5)

ULID:

    
    
      0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                      32_bit_uint_time_low                     |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     16_bit_uint_time_high     |       16_bit_uint_random      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       32_bit_uint_random                      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       32_bit_uint_random                      |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    

UUID, version 1:

    
    
      0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          time_low                             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |       time_mid                |         time_hi_and_version   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         node (2-5)                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

~~~
alizainf
Over time, UUID has been massaged and adapted to fit many different
applications, with the actual similarities between different versions
whittling down to 2:

    
    
      - data types used in binary representation (in order: u32, u16, u16, u8, u8, u16, u32)
    
      - canonical string representation (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx)
    

I am of the opinion that this has diluted the usefulness of UUID, especially
in specific circumstances. With this in mind, ULID was designed for
applications that require the following:

    
    
      - distributed ID generation amongst loosely coordinated servers (ie. those that don't have incentives to maliciously manipulate timestamps)
    
      - sortability of items with assigned ID without any additional information (ex. no additional db joins/requests)
    

Finally, ULID was designed with the explicit intent of being as character
efficient as possible, for use in URLs and such. By using the Base32 alphabet,
it uses fewer characters than UUIDs, optimizes for human readability/clarity
(Crockford's modifications) and remains case-insensitive.

For any API driven web-app where both the client and server can generate new
data, ULIDs can be ideal. A lot of people are already using something similar.
I thought it would be nice to standardize it as a drop-in replacement.

------
im_dario
Just being curious, I ported it to Go [0] to benchmark it.

[0] [https://github.com/imdario/go-ulid](https://github.com/imdario/go-ulid)

