Hexadecimal strings typically contain 0–9 and a–f, which gives plenty of opportunity for (naughty) words to form,1 e.g. “deadbabe”.
If we also accept “9” as a substitute for “g,” then even more (naughty) words can be built, e.g. “defacedfa9”. Your imagination is the limit.
Remove vowels
To avoid accidentally generating words, we can remove vowels (A E I O U, and arguably Y) from the list of possible characters, and additionally remove characters that can stand in for vowels (0 1 3 4).
The set of characters we use for representing hexadecimal strings therefore becomes shifted: instead of 0123456789abcdef, we now have 256789bcdfghjklm.
Performing this replacement is trivial with tr on the command line:
% echo 1337cafebabe |
tr 0123456789abcdef 256789bcdfghjklm
577cjgmlhghl
Ruby’s String#tr does the same:
'1337cafebabe'.tr(
'0123456789abcdef',
'256789bcdfghjklm',
)
# => "577cjgmlhghl"
Remove ambiguous characters
We can go further and remove ambiguous characters as well. While not necessary, it is helpful when writing down hexadecimal strings (especially when using non-conventional characters, like we do).
Ambiguous characters include B D G J Q S Z and 0 1 2 5 6 8 (with 0 and 1 already removed because they can substitute a vowel). The set of characters we use for representing hexadecimal strings has shifted again: instead of 256789bcdfghjklm (which replaced 0123456789abcdef), we now have 79cfhklmnprtvwxz.
We can use it the same way. Command line:
% echo 1337cafebabe |
tr 0123456789abcdef 79cfhklmnprtvwxz
9ffmvrzxtrtx
Ruby:
'1337cafebabe'.tr(
'0123456789abcdef',
'79cfhklmnprtvwxz',
)
# => "9ffmvrzxtrtx"
Note how 79cfhklmnprtvwxz is exactly 16 characters and ends with z. A wonderful coincidence.