今天我遇到了一个有趣的问题,并在互联网上搜索寻找解决方案,但没有找到任何。问题是这样的:随机的1对1散列函数
用户创建一个帐户,并给他一个唯一的ID号码,如123,来表示他的帐户。当另一个用户创建一个帐户时,我可以给最近创建的ID号码加1,并将其分配给他(124)。但是,这并不完全匿名每个人,因为他现在知道用户123在他之前注册。一个非常小的问题,但在一些可能的情况下,这可能会导致更大的问题。
更好的解决方案是让ID随机但唯一,这样就不会有人知道谁先来了。
为了解决这个问题,可以使用标准的散列函数或随机数发生器为每个人创建一个唯一的ID,但是然后碰到碰撞的可能性。这可以通过检查碰撞并再次运行来避免,但是对于这个例子来说,这会使系统太慢。或者可能是发电机运行的信息不完整,无法检查是否有碰撞。
我想出了一个不同的想法,就是基本上有一个洗牌的卡片组,你可以随时储存,并在任何时候需要一个新的ID。当你在套牌中用尽卡牌时,你会在最后一张牌组中的最高卡牌上继续一个新套牌,然后洗牌。缺点是你必须储存这副牌,如果你不小心失去了套牌,你会遇到许多问题,试图重新创建它,或者没有它就继续下去。
这一个非常类似的解决方案是每次重新创建基于固定种子的洗牌甲板,并取代甲板上的第n张牌而不是顶部。这样做的问题是,每当你需要一张新卡时,洗这个卡组可能会很昂贵。
我试图提出的其他数学模型都存在序列中的下一个数字是可预测的问题(每个数字与前一个数字相距一定数量)。他们中的很多人也有碰撞的问题。
所以我的问题是:是否有一些数学模型,我可以插入数字来获得独特的ID,不需要使用存储在内存中的“deck”(读取:数组),或在每次函数调用时重新计算。
例如
randomID(number, seed, range)
randomID(1,123,1000) = 284
randomID(2,123,1000) = 739
randomId(3,123,1000) = 088
randomId(3,888,1000) = 912
我已经看过了https://code.google.com/p/smhasher/wiki/MurmurHash3这似乎是有前途的,但我不认为它适用于对数字的任意范围,只有在32位或64位。
恭喜!你刚刚想出了GUID:http://stackoverflow.com/questions/371762/what-exactly-is-guid-why-and-where-i-should-use-it – trailmax
不知道为什么trailmax的答案是一个评论,但这是一个很好的答案。大多数语言都有一个库来生成一个GUID。价值并不保证是独一无二的,但碰撞的可能性是天文数字小,对于所有的实际目的,它们都是独特的,无序的ID。 –