Codec for UUID Slugs.
A UUID Slug is a shorter string representation that can be safely included in
URLs and file names.
The
SlugCodec turns a UUID into a string that does not start with
digits (0-9). Due to the default base-64-url alphabet, it is *case sensitive*
and may contain '-' and '_'.
The
Base32Codec can be passed to the
SlugCodec constructor to
generate base-32 slugs. Due to the base-32 alphabet, it is case insensitive
and it contains only letters (a-zA-Z) and digits (2-7). This encoding
substitution can be done to avoid the characters '-' and '_' of the
base-64-url encoding, but it makes the slug case insensitive.
To turn a UUID into a slug, the version and variant nibbles are are moved to
the first position of the UUID byte array. The slugs generated of the same
UUID version show a constant letter in the first position of the base-64-url
string.
This is how the UUID bits are rearranged:
00000000-0000-V000-X000-000000000000
| | ^
,-------------' | encode |
|,-----------------' | decode
|| v
VX000000-0000-0000-0000-000000000000
shift >>
V: version nibble or character
X: variant nibble or character
This table shows the slug prefixes for each UUID version:
VERSON PREFIX EXAMPLE
1 G GxA1e7vco3Ib6_mjtptP3w
2 K KryezRARVgTHLQ3zJpAXIw
3 O O9JfSS1IqIabkEWC-uXWNA
4 S S5iPSZYDt7q2w0qiIFZVwQ
5 W WY-Uv6WAY5os7Gfv4ILnvQ
6 a aMKkEoaymw0FSQNJRDL7Gw
If you don't like the change in the bytes layout before the encoding to
base-64-url, use the
Base64UrlCodec instead of
SlugCodec to
generate slugs.
SlugCodec and
NcnameCodec are very similar. The difference
between the two is the bit shift they do with the original UUID to transform
it into a string.
In the case someone is interested in implementing this type of slug in
another language, the change in the bytes layout don't have to be done with
bit shifting. Since a base-16 character corresponds to a nibble, the layout
change could be easily done by moving characters instead of by shifting bits.
See
SlugCodecTest#moveCharacters().
See: https://github.com/f4b6a3/uuid-creator/issues/30