【问题标题】:Can I be sure that this will always returning a unique alphanumeric string?我可以确定这将始终返回一个唯一的字母数字字符串吗?
【发布时间】:2020-10-28 01:52:39
【问题描述】:

我正在尝试在 javascript 中通用一个普遍唯一的字母数字字符串。我尝试使用 UUID,但格式不理想。目前我正在做以下事情:

Math.floor((Math.random() * Date.now())).toString(16).toUpperCase()

这会产生如下字符串:4198A8BEA4。这是所需的格式和相对长度。

我可以确定这将始终返回一个唯一的字母数字字符串吗?

如果是这样,我怎么能确定?

【问题讨论】:

  • 你不能确定。
  • 有可能一个随机数和一个时刻生成相同的字符串.....
  • 你能解释一下为什么吗? @Pointy
  • 当前时间戳和.random() 函数返回的值可能极不可能产生重复先前产品的产品,但这并非不可能。
  • 旁注:使用 UUID 的全部意义在于,从统计上讲,两次生成相同 UUID 的概率实际上为零。对于 10 个字符的字符串,重复的概率要高得多(尽管仍然相当低)。

标签: javascript unique


【解决方案1】:

不,生成的字符串可能有 10 或 11 个字符,字符从 1 到 F 不等,因此有 16 ** 10 = 1099511627776 种可能性。

冲突的可能性 - 对于大多数代码来说可能已经足够了 - 但它不是零。

为了保证不发生冲突,最简单的方法是使用数字索引,并在每次需要新索引时递增。

let i = 0;
const getNextUnique = () => i++;

console.log(getNextUnique());
console.log(getNextUnique());

不过,索引很容易在结果中看到。如果这对您来说是个问题,请在上面使用one-way hash function without collisions。 (不过,即使是加密哈希函数也可能发生冲突,depending on the algorithm

SHA-256 没有任何已知的冲突,这样的冲突被认为是near impossible under current circumstances,所以如果你愿意,你可以could use it

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());
})();

【讨论】:

  • ...或者只使用完整的 16 字节 UUID,这实际上也没有发生冲突的机会。
猜你喜欢
  • 2020-05-07
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2014-07-14
相关资源
最近更新 更多