Thanks for all the improvement suggestions! Taking them into account, the `makeSlug` function becomes:
function makeSlug(length: number): string {
const alphabet = "0123456789abcdefghjkmnpqrstvwxyz";
let result = "";
for (let i = 0; i < length; i++) {
result += alphabet[crypto.randomInt(alphabet.length)];
}
return result;
}
Having a zero in your alphabet can be problematic, because leading zeros are often stripped (e.g. Excel notoriously mangles phone numbers thinking they are integers).
Multiple calls to a randomness generator can be expensive, and a waste of entropy; production-scale random string generators should still respect this and ask for a block of bytes, then encode them, but with bias correction. You're off the hook in this case, I think node's implementation of randomInt is doing exactly that for you and conserving remaining entropy in a cache.
I think that 0 and 1 are likely to cause problems when customers end up reading their "user ID" back to your employees in Customer Support Country over the phone.
"It's one-three-oh-dee-ee-el. Yes, I'm sure, EL as in elephant."
So a user can confuse 1 for l, 0 for o, I for l, u for v, uppercase, lowercase etc, or the agent can say any of those over the phone, and it won't matter.
Every base-32 style encoding is Crockford at the core. The difference is in the alphabet, and also whether it requires padding or not (safe32 does not).
Crockford also incorporates error correction, which is unnecessary in modern systems since the underlying protocols do that already.
My favourite ambiguous readback is to say "M for Movember".
I have a note from a few years ago that 367CDFGHJKMNPRTWX may be a sufficiently unambiguous alphabet. Drop the one you like the least (probably N) to obtain a faux hex encoding.
Anything that needs to be read over the phone should probably be written out using something like the NATO phonetic alphabet, split into smaller chunks if needed: "The code? It's kilo eight niner; one three mike; delta echo lima."
Having come from a military background where using that is second nature, I'm constantly surprised how rarely I meet civilians who understand it effortlessly. When picking up a package I say "the code is Oscar Foxtrot three-fife" and you see the person processing for a long time to extract the first letter of the word. I've started saying "OF, that's Oscar Foxtrot, 3-5" to help them out.
In other words, asking a customer/consumer to be able to recite something in phonetics is not realistic in most cases.
Fortunately the code already takes this into consideration and removes ambiguous characters.
My experience in the USA is that if I don't include the phrase "as in" (as in "X as in Xray") most people still will not realize what I am doing (the alternative "for" can be confused with the digit.)
I also ask them to check my readback of key information they have given me and vice-versa; usually that works well.
One can convert those to the correct characters. Since “oh” and “el” are excluded from the alphabetic range, they become “zero” and “one” - deciding whether that is done in software for the help desk, or in the brain of the help desk staff is left as an exercise to management.
If you are trying for URL safe, Unicode is problematic because of Punycode conversions and differing browser behavior with Unicode URLs. (Some browsers always show Unicode as Unicode in URLs. Some browsers always show Unicode as Punycode in URLs. Some browsers switch between the two based on a huge number of variables such as gTLD, user preference, phase of the moon, etc.)
I happen to know that the biggest ski resort reservation system in Scandinavia contains a function called MaybeOnATuesday(), but to my knowledge it's never called.
Yeah...what I'd really like to do would be to give a character a "natural" background color, e.g.
Then its simple for support to say "red is one, green is ell". But you can't just add a color to a character, because copy paste/rich formatting don't work everywhere, or even transfer well...
Alternatively, if you use ⓪ and ⒈ it matters less if the user says "at" or "zero", and more that they didn't say "oh" or "one".
One thing I’ve been looking for in an ID generator is a way to supply a blocklist. There are a number of character combinations I’d like to avoid in IDs, because they might be offensive or get stuck in filters when copy-pasted (e.g. in a URI).
This can be solved in user space by regenerating if the character sequences are detected, but this a) skews the distribution, and b) potentially takes time, especially when the ID generator is made to not be “too fast”. I want to generate a single ID that passes the blocklist in a timeframe that is not too fast, if that makes sense.
Is there an ID generator that takes this into consideration?
This is why an open source project is now "CK Editor". It was the author's initials, but too many people saw an extra vowel in the name of the project.