我发现了许多关于生成 UID 的不同问题,但据我所知,我在这里的要求有些独特 (ha)。
总结一下:我需要生成一个非常短的 ID,它是“本地”唯一的,但不必是“全局”或“普遍”唯一的。这些限制不仅仅是基于美学或空间问题,而是因为它本质上被用作硬件标签,并且受硬件限制。以下是规格:
硬性要求
- ID 必须只包含十进制数字(基础数据是 BCD);
- ID 的最大长度为 12 个字符(数字)。
- 必须离线生成- 数据库/网络连接并不总是可用!
软要求
- 我们希望它从日历年和/或月份开始。由于这确实浪费了很多熵,我不介意在此方面妥协或完全废弃它(如有必要)。
- 从特定机器生成的 ID 应该是连续的。
- ID 不必按机器排序 - 例如,机器 1 吐出 [123000, 124000, 125000] 和机器 2 吐出 [123500, 123600, 124100] 非常好。
- 然而,从集体的角度看,越顺序化越好。一组像 [200912000001, 200912000002, 200912000003, ...] 这样的 ID 将是完美的,尽管这显然不能跨多台机器扩展。
使用场景:
- 该方案范围内的 ID 将由 10 台,最多 100 台不同的机器生成。
- 生成的 ID 总数不会超过几百万。
- 并发性极低。单台机器不会比每 5 分钟左右更频繁地生成 ID。此外,很可能一次不超过 5 台机器会在同一小时甚至同一天生成 ID。我预计一天内在给定机器上生成的 ID 少于 100 个,而所有机器的 ID 少于 500 个。
- 少数机器 (3-5) 很可能负责生成超过 80% 的 ID。
我知道可以使用少于 12 个十进制数字将时间戳编码到 100 毫秒甚至 10 毫秒的精度,这足以保证此应用程序的“足够唯一”ID。我之所以在这里问这个问题,是因为我真的很想尝试在其中合并人类可读的年/月,或者编码一些关于源机器的信息,或者两者兼而有之。
我希望有人可以帮助在这些软要求上做出妥协……或者解释为什么在其他要求的情况下它们都不可能。
(PS 我的“本机”语言是 C#,但如果有人有任何绝妙的想法,任何语言甚至伪代码的代码都可以。)
更新:
既然我有机会睡在上面,我想我实际上要做的是默认使用时间戳编码,并允许各个安装通过定义自己的 2 或3 位机器 ID。这样一来,想要弄乱 ID 并打包人类可读信息的客户可以自行找出确保唯一性的方法,我们不对滥用行为负责。如果机器恰好在进行所有在线安装,也许我们可以通过提供一个服务器实用程序来处理机器 ID 来提供帮助。