Python 哈希(time.time())是否总是唯一的

Python 哈希(time.time())是否总是唯一的,python,time,hash,Python,Time,Hash,我正在尝试为一些单元测试生成唯一的ID数字,我在某处看到了使用以下内容的建议: def unique_id(): time.sleep(0.000001) # smallest precision for time.time() return time.time() 我想知道hash()调用是否总是至少需要0.000001,因此我可以使用: def unique_id(): return hash(time.time()) 如果我在单线程应用程序中连续调用它,它会返回

我正在尝试为一些单元测试生成唯一的ID数字,我在某处看到了使用以下内容的建议:

def unique_id():
    time.sleep(0.000001) # smallest precision for time.time()
    return time.time()
我想知道hash()调用是否总是至少需要0.000001,因此我可以使用:

def unique_id():
    return hash(time.time())
如果我在单线程应用程序中连续调用它,它会返回相同的值两次吗


编辑:加粗“数字”一词,因为每个人都忽略了它。

如果需要唯一值,建议使用该库。 例如:

如果只需要数字值,请使用库


从Python提示符中回答这个问题很简单:

>>> import time; print hash(time.time()) == hash(time.time())
True
(如果你看到
False
,你只不过是运气好而已。)

所以,是的。现代计算机的运算速度很快,可以在0.000001秒内将浮点值散列出来。事实上,当我把它写成一个递增计数器的
循环时,似乎在我的机器上,Python可以获得时间并将其连续散列5000次以上,而没有看到任何差异。毫不奇怪:哈希用于将对象拟合到哈希表(字典)中,因此它的主要要求之一是速度

在任何情况下,都不要求或保证
hash()
为每个对象返回唯一标识符。
time.time()
(或任何类型)的两个不同值可以具有相同的哈希,并且没有任何东西可以阻止这两个值根据某种定义“相邻”


正如其他人所指出的,您想要的是UUID。不要重新发明轮子。如果您不能使用UUID,请使用无法复制的东西,例如计数器。

Evan Fosmark已经介绍了它


但我想补充一点,Python的“hash”函数仅为32位或64位。我甚至不知道它是如何实现的,但我怀疑它是随机加密的。低质量散列函数可能会发生冲突。

除非时间完全相同,否则不会。
time.time()
返回一个始终递增的浮点值,因此您应该是安全的。为什么不直接使用UUID类而不是创建自己的类呢?请参阅我对Evan Fosmark的回复,了解UUID不适用于此的原因。根据该评论,您有“我正在处理许多db字段”。等等,你有数据库吗?为什么不从数据库中获取自动递增整数?“主键/自动递增整数”的整个要点就是要解决这个确切的问题!正确的插入(使用正确设计的数据库)是最好的解决方案。另一个解决方案是在数据库级别创建一个唯一的索引。所讨论的“ID”不是主键。例如,我想生成一个特定类型的随机对象。我有一个函数,它将生成对象的基本数据,并依赖插入数据库来生成PK。但也有一个名为“obj_name”的字段,它有一个唯一的索引。调用该对象生成器时,我需要为无法使用基础数据的任何字段生成唯一值,因此当前我在time.sleep(0.000001)之后执行“name%x”%(time.time()*1e6)。这是可行的,但我想我应该尽量简化它。我处理的许多db字段都有不同的限制。例如,在整数字段或限制为16个字符的字段中,UUID不起作用。对于限制为16个字符的字段,只需获取UUID的一部分。对于整数字段,为什么不使用
random
库呢?有些测试用例针对的是不提供清除旧记录功能的远程API。通过使其基于时间,我试图避免与以前运行的测试套件的结果发生冲突的可能性。使用部分UUID是错误的,UUID中的所有字节都不具有相同的随机性。@GeraldThibault:
int(UUID.uuid4())
在需要整数时有效
os.uradom(16)
获取16个随机字节。您应该编辑您的问题并添加与您的案例相关的任何限制,例如,您不应该使用默认的随机数生成器,例如在安全相关代码(密码、身份验证等)中使用的
random.randint()
,您可以改为使用
random.SystemRandom()
。相反,在计算机模拟中,时间性能和统计特性可能比安全性问题更重要,您可能会做出相反的选择。我甚至在发布之前就进行了测试,使用了与您发布的相同的样本行,但从未见过相同的值。我不确定更快的机器是否会有不同的结果,这就是为什么我问。而且,“每秒5000次”仍然大于.000001的时间差,因此如果它是每秒5000次而没有看到差异,那么散列过程仍然需要足够长的时间来强制结果时间是唯一的,对吗?“每秒5000次”是一个错误,它真的连续测试了5000次。整个脚本在4.5秒内运行,测试了1000次while循环迭代,循环直到看到不同的散列。
>>> import random
>>> INT_MAX = sys.maxint #  Set INT_MAX to the max value for your given INT column
>>> random.randint(0, INT_MAX)
5188925271790705047
>>> import time; print hash(time.time()) == hash(time.time())
True