Seven Is A Magic Number: Why 7 Letter Codes Make Sense

by Finnian Reilly (modified: 2023 Dec 18)


A lot of psychological research going back to the 1950's has shown that, on average, the longest sequence a normal person can recall on the fly amounts to about seven items. Psychologists have dubbed this limit as the "magical number seven". It equates to the capacity of what's has been termed "the brain's working memory".

For this reason human friendly unique identifiers would ideally have a maximum of 7 characters. But how to make a big enough range ..

Base 32 VS Base 16 Codes

The UUID_GENERATOR class can be used to generate a UUID as a hash of the current system time. The can then be used to generate a unique 7 character code. The simplest way is obtain it would be with the lines:

code := uuid.data_5.hex_string code.keep_tail (7)

However the number 0xFFF_FFFF (28 bits) only approximates 268 million. Given the current world population, this is not sufficient to make a globally unique number for every human.

But if we increase this to 5 x 7 bits and use the letters from A to V to accommodate base 32 numbers, we can store 35 bits, increasing the permutations to over 34.36 billion.

Of course you could also use base 64 for maximum range, but codes like this are much more difficult to remember as you also have to remember the case of the letter, as well as the odd punctuation character.

To facilitate this conversion from a UUID, I have added the function to a descendant.

class EL_UUID inherit UUID feature -- Access to_7_character_code: STRING -- trailing 35 bits of `data_5' represented as uppercase base 32 number -- (Approx 34.36 billion permutations) local data: NATURAL_64; i, quintet: INTEGER do create Result.make_filled (' ', 7) data := data_5 from until i > 6 loop quintet := (data & Quintet_mask).to_integer_32 inspect quintet when 0 .. 9 then Result [7 - i] := '0' + quintet when 10 .. 31 then Result [7 - i] := 'A' + (quintet - 10) end data := data |>> 5 i := i + 1 end ensure size_is_7: Result.count = 7 equal_to_trailing_35_bits_of_data_5: base_32_as_integer_64 (Result) = data_5 & Thirty_five_bit_mask end feature -- Contract Support base_32_as_integer_64 (code: STRING): NATURAL_64 local converter: EL_BASE_32_CONVERTER do Result := converter.to_natural_64 (code) end feature -- Constants Quintet_mask: NATURAL_64 = 0x1F Thirty_five_bit_mask: NATURAL_64 = 0x7FFFFFFFF end

Where to put class UUID

As an aside..

For the longest time I was unsure which library was best suited to house EL_UUID. But now I figure it belongs in encryption.ecf. Hash functions and digests are used a lot with encryption classes, and UUID's are usually generated as hash of the system time.


  1. In the Brain, Seven Is A Magic Number