Sheldon
Sheldon

Reputation: 215

Can I be sure that this will always returning a unique alphanumeric string?

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

Answers (1)

CertainPerformance
CertainPerformance

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

Related Questions