Reputation: 215
I'm trying to generic a universally unique alphanumeric string in javascript. I've tried to use UUID but the format isn't desirable. Currently I am doing the following:
Math.floor((Math.random() * Date.now())).toString(16).toUpperCase()
This results in a string like: 4198A8BEA4
. This is the desired format and relative length.
Can I be sure that this will always return a unique alphanumeric string?
If so, how can I be sure?
Upvotes: 0
Views: 131
Reputation: 370809
Nope, the resulting string will probably have 10 or 11 characters, and the characters will vary from 1 to F, so there are 16 ** 10 = 1099511627776 possibilities.
The likelihood of a collision is low - it'll probably be good enough for most code - but it's not zero.
To guarantee no collisions, the easiest way would be to use numeric indicies instead, and increment each time a new one is needed.
let i = 0;
const getNextUnique = () => i++;
console.log(getNextUnique());
console.log(getNextUnique());
The index is easy to see in the result, though. If that's a problem for you, use a one-way hash function without collisions on it. (though, even cryptographic hash functions can have collisions, depending on the algorithm)
SHA-256 does not have any known collisions, and such a collision is considered near impossible under current circumstances, so you could use it if you wanted:
let i = 0;
const getNextUnique = async () =>
Array.prototype.map
.call(
new Uint8Array(
await crypto.subtle.digest("SHA-256", new TextEncoder().encode(i++))
),
(x) => ("0" + x.toString(16)).slice(-2)
)
.join("");
(async () => {
console.log(await getNextUnique());
console.log(await getNextUnique());
})();
Upvotes: 1