Python - 使用参数生成32位随机int

时间:2013-10-25 11:30:31

标签: python random header

我需要生成一个32位的随机int,但取决于一些参数。该想法是为通过自己的P2P网络发送的每条消息生成唯一ID。为了生成它,我想作为参数:我的IP和时间戳。我的问题是,如何从这些参数中生成这个32位随机int?

再次感谢!

3 个答案:

答案 0 :(得分:2)

这是一个包含相关问题的选项列表:

  1. 使用随机数。你会在大约一半的比特中得到一个碰撞(非唯一值)(这就是“生日碰撞”)。因此对于32位,您会在2 * 16条消息后发生冲突。如果您发送的消息少于65,000,这不是问题,但65,000不是一个很大的数字。

  2. 使用某些服务的顺序计数器。这就是twitter的雪花所做的(见这里的另一个答案)。麻烦的是通过网络提供这些。通常使用分布式系统,您可以为每个代理提供一组数字(因此A可能会得到0-9,B得到10-19等),然后他们使用这些数字然后请求新的块。这减少了网络流量和服务提供数量的负载。但这很复杂。

  3. 从某些值中生成哈希,这些值将是唯一的。这听起来很有用,但实际上并不比(1)好,因为你的哈希会发生碰撞(我在下面解释原因)。所以你可以哈希IP地址和时间戳,但你所做的只是生成32位随机数,实际上(不同之处在于你可以重现这些值,但看起来你似乎不需要那个功能),并且所以你再次发出65,000条消息后会发生碰撞,但这并不多。

  4. 更聪明地生成ID以保证唯一性。 (3)中的问题是您正在散列超过32位,因此您正在压缩信息并获得重叠。相反,您可以显式管理位以避免冲突。例如,为每个客户端编号为16位(允许最多65,000个客户端),然后让每个客户端用户使用16位计数器(每个客户端最多允许65,000条消息 ,这是对(3)的重大改进)。那些不会碰撞,因为每个都保证是独一无二的,但是你的系统有很多限制,事情开始变得复杂(需要为客户编号并为每个客户存储计数器状态)。

  5. 使用更大的字段。如果您使用64位ID,那么您可以使用随机数,因为每2 ** 32条消息就会发生一次冲突,实际上从不(4,000,000,000)。或者您可以使用32位时间戳加入IP地址(32位)(但要小心 - 这可能意味着客户端每秒不超过1条消息)。唯一的缺点是带宽略大,但在大多数情况下,ID比有效载荷要小得多。

  6. 个人而言,我会使用更大的字段和随机数字 - 它很简单且有效(尽管好的随机数在嵌入式系统中是一个问题)。

    最后,如果您需要将值“真正”随机(因为,例如,使用ID来确定优先级,并且您希望事情变得公平)那么您可以使用确定性值并重新使用上述解决方案之一 - 将比特排列为伪随机。例如,反转计数器中的位可能就足够了(先比较lsb)。

答案 1 :(得分:1)

我建议使用某种哈希值。有许多可能的哈希值,FNV hash有各种各样的大小并且速度很快。如果你想要加密安全的东西,它会慢得多。您可能需要添加一个计数器:1,2,3,4 ...以确保您不会在同一时间戳内获得重复的哈希值。

答案 2 :(得分:1)

您是否尝试过调查Twitter的Snowflake?它有一个Python包装器。