It seems the algorithm is equivalent to:
function nanoid(alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_") {
return Array.from(crypto.getRandomValues(new Uint8Array(21)), i => alphabet.charAt(i & 63)).join('');
}
(Maybe String.fromCharCode() is slightly faster than Array.join(), but I doubt it matters much.)On node.js it's even easier, since url-safe base-64 encoding is supported natively:
Buffer.from(crypto.getRandomValues(new Uint8Array(16))).toString('base64url').substring(0, 21)
Do we really need an entire Github project dedicated to a 1-liner?* Using uncoordinated random generation in a large address space for IDs is often a very useful idea
* 128 bits is a good rule of thumb for "will never ever collide"
* Making this into a heavyweight "UUID" concept, with it's own bespoke string format, and 7 different standard ways to generate them, feels like a ridiculous waste of cognitive effort that makes such a simple concept appear opaque and magic. If you want to encode other data (timestamp, node ID) in 16 bytes you can still do that of course. There's no need for anyone else to even know. Just do some quick calculations to ensure you haven't eliminated too much entropy
It depends.
True random number are slow. Fast PRNG are prone to collision. That's why we have different specs and versions of UUIDs.
Not in this decade. You can slam out a million securely random 128 bit numbers per second per core. For numbers you will store, the effort to store them is orders of magnitude greater than the effort to generate securely.