Language agnostic 生成唯一的参考号策略

Language agnostic 生成唯一的参考号策略,language-agnostic,uniqueidentifier,Language Agnostic,Uniqueidentifier,人力资源管理。。。这是我的CS知识让我失望的地方。我想写一个生成唯一参考号的算法 我不想使用序列号,因为它们会带来安全风险,我想使用 字母数字法。ref也将有一个最小和最大长度。(我不能使用GUID,因为它太长) 理想情况下,我不想查询我的持久层来查看是否以前使用过ref 我可以采用什么策略?如果您担心安全风险,那么您需要一个加密安全的随机数生成器。您应该能够告诉它您需要多少字节(即数字的长度)。如果这个数字会被人类引用,我建议您在解决方案中遵循以下准则: 如果不能与数据库同步以查看下一个数字

人力资源管理。。。这是我的CS知识让我失望的地方。我想写一个生成唯一参考号的算法

我不想使用序列号,因为它们会带来安全风险,我想使用 字母数字法。ref也将有一个最小和最大长度。(我不能使用GUID,因为它太长)

理想情况下,我不想查询我的持久层来查看是否以前使用过ref


我可以采用什么策略?

如果您担心安全风险,那么您需要一个加密安全的随机数生成器。您应该能够告诉它您需要多少字节(即数字的长度)。

如果这个数字会被人类引用,我建议您在解决方案中遵循以下准则:

如果不能与数据库同步以查看下一个数字,并且不能使用guid或较长的随机字符串,则需要在ID中包含某种本地值

e、 例如,如果所有客户端都在一个已知网络上,则可以在每个客户端的ip地址D块中结束每个号码


或者,如果客户端必须登录,并且每个用户一次只能登录一次,则可以将其用户ID包含在某个位置的数字中。

将GUID截断为所需的大小


如果您正在生成数字,除非它们是随机的和巨大的,否则最好检查它们是否已经被使用过。

我在这里暗中试探一下,但是…您想要一个唯一的随机值,但不超过16字节。您最好的选择仍然是一个只有16字节的GUID…您想使用字母数字,所以…有一些选项

使用GUID但对其进行编码base64看起来像7QDBkvCA1+B9K/U0vrQx1A,它是22个字节,仍然比本机GUID长…但比典型的字符串表示形式短

请参见此处的文本编码:

另一个选项是对Guid进行散列,但会失去一些唯一性,那么对于非唯一项,您的容忍度是多少

==========

假设你有一个进程插入到表中,你可以使用一个HiLo算法,并且确信你不必每次都点击DB。您只需将最后一个高值存储在内存中……当进程启动时,您将点击数据库以查找您的中断位置:


我仍然认为Guid是您最好的选择……16字节并不坏,它与您提出的大多数字母数字解决方案一样小。

一种方法可能是基于较小的数字子集生成数字。例如,可以使用二进制序列根据戈德尔编号生成。例如,将000映射到5z、3y、2x上的111会产生0、2、3、6、5、10、15、30


当然,这过于简单化了。但是,通过迭代“salt”编号来生成参考编号,您根本不必跟踪参考编号。如果,或者当然,你有理由确信你不必考虑碰撞i、 e.microtime()+rand(100009999)

我在一个生产系统中成功地做到了这一点:

  • 取当前时间(UTC,精度为微秒)
  • 您的进程id、线程id
  • 您的计算机名
  • salt值(基本上只是程序特有的字符串)
  • 随机值(最好是加密级PRNG)
将其放在内存中,或者作为字符串,或者将值异或在一起,或者类似的方式。 然后:

  • 用SHA-1之类的杂凑词来表达
  • 对生成的数字执行mod N以将输出缩小到N字节
  • 如果需要,可以转换为十六进制或可打印的格式
请注意,将UID压缩到N个字节将增加 液体碰撞


第一个列表中的所有输入数据都是为了确保如果您有一个由许多计算机组成的集群,那么您可以获得一个唯一的散列基。您可以省略其中的一些,但必须确保其中包含的某些内容使生成UID的每台计算机都有所不同。

为什么序列号会带来安全风险?因为您可以猜测下一个数字是什么。想象一下,如果你的银行按顺序分配账号……你可以很容易地找到账号的范围。除非你添加代码来处理冲突,否则我不建议使用这种方法。截断会造成一个伤害的世界——请参阅本文