如何使用较小的" global"?

时间:2016-03-08 01:10:23

标签: guid

我有自己的应用程序,更小的"全球"比我们真实的全球,我想要更短版本的GUID。现在假设我有我估计不会超过的具体ID数(例如1亿个ID)。如何确定与GUID具有相同属性所需的随机位数? (全球唯一,不需要中央权限来生成一个)使用正常的GUID将是一种过度杀伤。

我的"矫枉过正"指的是:我需要尽可能容易地键入/说/写下ID,并且同时具有与GUID相比具有天文数字的低碰撞机会。我听说GUID可以分配给地球上的每一粒沙子。我的应用程序是一个游戏,每个玩家获得一个ID生成,显然我的玩家不像地球上的沙子数量那么多。

如果玩家可以说喜欢"我的ID是XXXX-XXXX"那将是最好的。在这种情况下,我不太确定随机十六进制的8个字符对于1亿玩家来说是不够还是太多。 (实际上我把它编码为A-Z 0-9而不是十六进制)我的游戏不受在线限制,所以我希望每个玩家即使不在线也能获得唯一ID。 (没有服务器检查ID冲突)

GUID旨在全球独一无二。但我不知道为什么会导致128位序列。也许他们只是选择"非常大"一个是2的幂?在设计GUID时我不知道他们在想什么,以确保它不会发生冲突。 (他们使用世界人口时间的东西?如果是这样的话,我也可以使用1000万次。)

2 个答案:

答案 0 :(得分:2)

128位guid通常表现良好,因为大多数编译器足够聪明,可以将操作减少到一对64位操作(在某些CPU上,单个128位扩展操作)。 Java和C#/ VB.NET可能比C ++有更多的开销,但是如果你使用Java或C#/ VB.NET,你已经接受了相当多的开销,并且GUID不会增加太多它。

但是,如果您确实需要较小的值,则可以手动减少GUID,方法是将较高的64位与较低的64位进行异或(从而保留原始唯一性的)到创建一个紧凑的64位主要唯一数字。

您可以以类似的方式减少到32位或48位,始终是原始GUID大小的倍数。这样做的好处是,您开始使用的数字在非常大的集合中是唯一的。但是,请记住,1亿个项目需要相当多的位来保留不重叠的保证,因此如果您不小心,您可能会在以后为自己设置一个非常难以找到的问题。

粗略但可能同样有效的方法是使用加密安全的随机数生成器并根据需要构建一个尽可能大的数字(可能最小为48位)。重要的是不对结果进行模运算,否则可能会显着降低唯一性(由于随机数生成器的周期)。

我假设您不能使用顺序ID,尽管您可能想重新审视这个想法并查看是否有办法使顺序ID工作。例如,您可以使用与随机种子数配对的顺序ID,保证唯一性而不需要大数,并允许内部索引操作和大型数据集中常见的类似优化。

答案 1 :(得分:0)

好的,我和朋友讨论过并提出了解决方案。这是如何决定我的游戏ID的“字符”数量。

一个字符由0-9和A-Z组成,而不是HEX,即36种字符。我们取出0 O 1 I因此可以打印各种字体而不会混淆,留下32种字符。

然后,如果每个角色都是伪随机的,我们可以安全地拥有多少玩家?

我们使用JSFiddle的平方近似值。该页面中的公式表示有2个人碰撞50%的可能性需要多少人。生日问题是22.99人。 (365种可能的选择)

现在我们将32 ^ No.of字符替换为等式而不是365.这就是有多少玩家会导致2名玩家拥有相同ID的几率为50%:

Birthday paradox

最后,我们同意选择9个角色的身份证,这样游戏最多可以注册690万玩家,而所有游戏中只有6个玩家将拥有相同的ID(50%几率)。

游戏甚至不在线!只有当2名球员仍然在同一时间积极比赛并且决定在同一周内将得分发送到记分牌时,由于每周得分重置,它才会发生碰撞。因此,游戏可以容纳的实际数量会略高于此。 (游戏可能没有那么多玩家......这只是每个游戏初创公司的一个小小的幸福梦想。至少计算很有趣。)

它可能看起来更容易阅读:5XT-339-A67