javascript - 如何使用自定义字母表生成 GUID,其行为类似于 MD5 哈希(在 JavaScript 中)?

标签 javascript string unique uuid guid

我想知道如何在给定输入字符串的情况下生成 GUID,以便相同的输入字符串产生相同的 GUID(有点像 MD5 哈希)。 MD5 哈希值的问题在于它们只是保证低冲突率,而不是唯一性。相反,我想要这样的东西:

guid('v1.0.0') == 1231231231123123123112312312311231231231
guid('v1.0.1') == 6154716581615471658161547165816154716581
guid('v1.0.2') == 1883939319188393931918839393191883939319

你会如何实现这种事情(最好是用 JavaScript)?甚至有可能做到吗?我不知道从哪里开始。像uuid module之类的东西不要使用种子字符串,并且它们不允许您使用自定义格式/字母表。

我不是在寻找 canonical UUID format ,而是一个 GUID,理想情况下仅由整数组成

最佳答案

您需要定义文本字符串(例如“v1.0.0”)到 40 位长字符串(例如“123123...”)的一对一映射。这也称为双注入(inject),尽管在您的情况下,注入(inject)(从输入到输出的简单一对一映射,不一定是到)可能就足够了。正如您所注意到的,哈希函数不一定确保这种映射,但还有其他可能性,例如全周期 linear congruential generators (如果它们采用可以一对一映射到输入字符串值的种子),或其他可逆的功能。

但是,如果可能的输入字符串集大于可能的输出字符串集,则无法将所有输入字符串与所有输出字符串一对一映射(不创建重复项),因为 pigeonhole principle .

例如,您通常无法将所有 120 个字符的字符串与所有 40 位数字的字符串一对一映射,除非您以某种方式限制 120 个字符的字符串的格式。但是,如果您可以接受将输入字符串限制为不超过 1040 值(大约 132 位),或者如果您可以利用输入字符串,以便保证它们无损压缩到 40 个十进制数字(大约 132 位)或更少,这可能是也可能不可能。另请参阅 this question

该算法涉及两个步骤:

  • 首先,通过构建字符串的 charCodeAt() 值,将字符串转换为 BigInt,类似于另一个答案中给出的 stringToInt 方法。如果任何 charCodeAt() 为 0x80 或更大,或者生成的 BigInt 等于或大于 BigInt(alphabet_length)**BigInt(output_length),则抛出错误)
  • 然后,通过采用 BigInt 和输出字母表大小的模并将每个余数替换为输出字母表中的相应字符,将整数转换为另一个字符串,直到 BigInt 达到 0。

关于javascript - 如何使用自定义字母表生成 GUID,其行为类似于 MD5 哈希(在 JavaScript 中)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63503924/

相关文章:

c++ - 在 C++ `multimap` 中,如何有效地获取 `mapped_type` 元素的集合而不重复?

javascript - 将三元运算符的变量转换为 if-else 语句

javascript - 如何在应用程序启动时合并演练屏幕

javascript - 可以使用 javascript 更改图像调色板吗?

python - 将字符串拆分为整数部分和字符串部分的最佳方法是什么?

C++ 如何生成 10,000 个唯一的随机整数以存储在 BST 中?

javascript - 无法在 javascript selectize 中读取 undefine 上的属性 addOption

string - 如何 append 到 Rust 哈希表中的字符串值?

c - 释放为 C 中的一个很长的字符串 (char*) 分配的内存?

sql - 保持 RSS 提要在 sql 数据库中唯一的最佳实践