Blog

Human Friendly UUIDs - A Better Alternative

1. Introduction

Universally Unique Identifiers (UUIDs) or as they are also known as Global Unique Identifiers (GUIDs) are a great way to uniquely identify something, like an account, a property, or an order. They are long 128 bit numbers. Instead of being represented with decimal digits (0-9), they are represented by hexadecimal digits (0-9 and A-F), and come to a length of 32 characters. An example would be: fdea637057194b3ba505601212405f55. Usually to be a bit more readable dashes are used, when presenting them out, and final result may like this: fdea6370-5719-4b3b-a505-601212405f55

And while being one gigantic number, how are UUIDs are useful. Their usefulness is that when randomly generated the UUIDs are almost unique (sometimes referred as practically unique, but not guaranteed unique). Because of that characteristic, a UUID is an excellent candidate for a primary key, which can be used to uniquely identify a linked resource (i.e an invoice, a vehicle, an object, etc) in a database.

2. Why Normal UUIDs are Not So Useful to Humans?

But, while being practically unique, UUIDs tend to be of really little other help. First, being truely random and using hexadecimal digits they carry no meaning whatsoever to a human. And second, the random nature of the UUIDs means they cannot be ordered sequentially in the order they were generated.

While not seeming like much of a drawback, the above two characteristics are actually a HUGE drawback for a human. Primarily, because for humans attaching meaning to numbers, and being able to sequentially order and rationalize about them is a key strength. A key strength that we effectively lose once we start using UUIDs.

3. Introducing Human Friendly UUIDs - A Better Alternative

Below I introduce a new human friendly UUID (HUUID) version, which aims to remove these weaknesses. This is achieved by adding a human readable, meaningful time element, all while  preserving the practically unique feature and usefulness of the UUID format.

The human friendly UUID is a regular decimal human-readable number, which when generated incorporates the time of its generation in its format. The human friendly UUID contains the full year, hour, minute, seconds, and microsecond of its generation, followed by twelve random digits. This results in a format that looks like this: 20150105215121071500123412341234.

While still being a long number, the inclusion of a time element enforces the UUID with added context and meaning, making it more relatable and intuitive for human interpretation. This added layer of cognition allows people to attach meaning to the identifier, enabling them to quickly and easily place it within a broader comprehension frame.
For instance, in the case of invoice numbers, a human-friendly UUID can provide insight into the date and time at which the invoice was generated, unconsciously connect it with events that happened around this time, and also outright know if one invoice preceded the other.

Overall, the human-friendly UUID represents a uniqie solution that retains the core strengths of traditional UUIDs while keeping them totally human-centric.

4. Readability Matters -Introducing Dashes for Clarity

When humans are involved readability does make a major difference. Especially when they are displayed to users for reference purposes, such as in the case of invoice numbers, it is important to present them in a clear and readable format. To enhance readability, these UUIDs can be divided into four groups separated by dashes.

The first group represents the year, month, and day. The second group denotes the hour, minute, and second. The third group showcases the microseconds, and the final group is composed of a randomly generated number, which can be further subdivided into groups of four digits for added clarity.

An example of a human-friendly UUID in this format would be: 20150105-215100-071500-1234-1234-1234

Below is an example implemetation in PHP of such a human friendly UUID with formatting:

                echo date('Ymd-His').'-'.substr(explode(" ", microtime())[0],2,8).'-'.rand(0,999999999999);
            

5. How Practically Unique are the Human-Friendly UUIDs

While there may be room for debate, there is a compelling argument to be made that human-friendly UUIDs are, in practice, just as unique as their random counterparts, if not even more. The rationale behind this assertion lies in the irreversibility of time.

While it's true that the number of human-friendly UUIDs generated per second may be limited, once a second has passed, it's gone forever. This means that the window for potential duplication is finite, and once it has closed, the probability of two identical UUIDs being generated diminishes to near zero.

In contrast, the regular random UUIDs, while vast in number and in theory should prevent duplicate, in practice do occasionally lead to duplicates and therefore collisions.

Thus, while theoretically human-friendly UUIDs will be in less number than the random UUIDs, in practice the former's time-based element introduces an intriguing perspective on their relative uniqueness in a context that is temporally bound.

After all, once a second is gone, its gone FOR EVER, and can NEVER EVER return.

6. Human Friendly Unique ID - A Shorter and More Compact Alternative

While human-friendly UUIDs are great, their pure length can sometimes present a challenge in certain circumstances. To address this, a shorter version can be used: the Human-Friendly Unique ID (HUID). The HUID format incorporates a combination of date and time elements, along with microsecond and nanosecond components, in a more compact structure. This format for a Human Friendly Unique Id (HUID) still gives a practically unique ID, without claiming to be universal.

                YYYYMMDD-HHMMSS-MMMMMM-NNN

Note. MMMMMM - represent microseconds, and NNN - represent nanoseconds

If a higher level of uniqueness is not a critical priority, shortening the format to include only the year, month, day, hour, minute, and second components can provide a suitable compromise between uniqueness and brevity. The shortened result will be: YYYYMMDD-HHMMSS-MMMMMM or even YYYYMMDD-HHMMSS.

For instance, in the case of generating invoice numbers, a seconds-level precission can be more than enoughto guarantee practical uniqueness, while it will still retain the human-friendliness and the sequential effect of the identifier.

7. How Practically Unique are HUIDs

A nanosecond (ns) is a unit of time equal to one billionth of a second (10−9 or 1/1,000,000,000 s). Same is the chance for collision. However, this collision chance exists only this very nanosecond, and is gone the next. After that moment (one-billionth of a second window) has passed, the likelihood of a duplicate emerging diminishes to virtually zero.

In contrast, with random UUIDs, the chances of a collision incrementally increase as more UUIDs are generated. Though theoretically truely random UUIDs should have miniscule chance for collision. In practical terms as true randomness is difficult to achieve, pseudo-random UUIDs occasionally happens.

Thus, in terms of practical uniqueness, HUIDs can be considered a viable alternative to random UUIDs, offering a compelling balance between human readability and a high degree of distinctiveness, particularly within a specific time based context.

The decision to use HUIDs or random UUIDs ultimately depends on the requirements of the specific application. Yet, if the significance of human readability is high and you value your sanity, the HUUIDs are definitely the way forward.

8. Libraries for Generation of Human-Friendly UUIDs

If you're interested in implementing HUUIDs in your Go or PHP code, there are a few libraries that can help. Here are two that you can check out:

- https://github.com/gouniverse/uid

- https://github.com/Sinevia/php-library-uid

Both libraries provide comprehensive documentation and examples to help you get started with integrating HUUIDs into your codebase.