生成唯一的参考编号策略

时间:2008-12-10 17:16:00

标签: language-agnostic uniqueidentifier

Hrm ......这是我的CS知识让我失望的地方。我想写一个算法,生成一个唯一的参考号。

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

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

我可以采用哪些策略?

7 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

如果这个号码将被人类引用,我建议您在解决方案中遵循这些指南:

What is the best format for a customer number, order number?

如果您无法与数据库同步以查看下一个数字是什么,并且您无法使用GUID或相对较长的随机字符串,那么您需要在ID中包含某种本地值。

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

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

答案 2 :(得分:1)

我在黑暗中捅了一下但是......你想要一个独特的随机值,但不到16个字节。你最好的选择仍然是一个只有16个字节的GUID ....你想使用字母数字所以...一些选项。

使用GUID但编码它base64看起来像7QDBkvCA1 + B9K / U0vrQx1A这是22个字节,它仍然比原生Guid长......但比典型的字符串表示短。

请参阅此处的文字编码:http://en.wikipedia.org/wiki/Globally_Unique_Identifier

另一个选择是对Guid进行哈希处理,但是你会失去一些独特性,那么对于非独特项目你的容忍度是多少?

==========

假设您有一个插入表格的流程,您可以使用HiLo算法,并确信您不必每次都能访问数据库。你只需在内存中存储最后一个高值...当进程启动时你会去数据库找出你离开的地方:What's the Hi/Lo algorithm?

我仍然说Guid是你最好的选择.... 16个字节不错,并且会像你提出的大多数字母数字解决方案一样小。

答案 3 :(得分:0)

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

当然,这过于简单化了。但是通过迭代“盐”数来生成参考数字,您根本不必跟踪参考数字。提供或当然,您有理由相信您不必考虑碰撞因素。

答案 4 :(得分:0)

如果可能在您的应用程序/环境中,您是否考虑将时间作为伪随机生成数字的一部分添加?

即。 microtime()+ rand(10000,99999)

答案 5 :(得分:0)

我一直在生产系统中这样做成功:

  • 获取当前时间(UTC,精确到微秒)
  • 您的进程ID,主题ID
  • 您的电脑名称
  • 一个salt值(基本上只是程序特有的字符串)
  • 随机值(最好是加密级PRNG)

将其作为字符串放入内存,或将值与XOR一起或类似。 然后:

  • 用例如哈希SHA-1
  • 对结果数字执行mod N以将输出缩小为N字节
  • 如果需要,可以转换为十六进制或可打印的内容。

请注意,将UID缩小为N个字节会增加机会 UID-碰撞。

如果您拥有许多计算机的群集,则第一个列表中的所有输入数据都是为了确保您获得哈希的唯一基础。你可以省略其中的一些,但你必须确定它包含的内容会使你生成UID的每台计算机都有所不同。

答案 6 :(得分:-1)

将GUIDE截断为您想要的大小。

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