While reading some postfix documentation I came across this passage:
New queue files are created with names such as 3Pt2mN2VXxznjll.
These are encoded in a 52-character alphabet that contains digits
(0-9), upper-case letters (B-Z) and lower-case letters (b-z).
For safety reasons the vowels (AEIOUaeiou) are excluded from
the alphabet. The name format is: 6 or more characters for
the time in seconds, 4 characters for the time in microseconds,
the 'z'; the remainder is the file inode number encoded in the
first 51 characters of the 52-character alphabet.
First off, thank you to whoever took the time to write this down.
But why?
Let’s step through this:
We know what the queue IDs will look like: New queue files are created with names such as 3Pt2mN2VXxznjll
so far so good.
We know their encoding These are encoded in a 52-character alphabet
. Hm, a 52 character alphabet is a bit weird is it just upper and lowercase letters? As we see next, it’s digits (0-9), upper-case letters (B-Z) and lower-case letters (b-z)
. Starting from B is slightly weird too. And now we see why For safety reasons the vowels (AEIOUaeiou) are excluded from the alphabet
.
For safety reasons the vowels AEIOUaeiou are excluded from the alphabet.
Aside from being the same alphabet as an early 2000s startup name generator why are these vowels unsafe? Why can we can keep Y and y? Is it the part time vowel status?
Moving on to the rules for encoding a message:
- 6 or more characters for the time in seconds
- 4 characters for the time in microseconds
- the remainder is the file inode number encoded in the first 51 characters of the 52-character alphabet
What time? Unix time? System time? Just calling gettimeofday()? It’s gettimeofday. A quick aside: Postfix doesn’t maintain any sort of source control repository and just distributes code via tarball o_O.
On to the best part the remainder is the file inode number encoded in the first 51 characters of the 52-character alphabet
.
And now we throw out another one of the characters from our 52 character alphabet and only use the first 51 for whatever is left after getting the time. The reason for this is that the time/inode separator is ‘z’.
After digging through all of the configuration references and source code I’m left wondering, wait…but why?