我需要找到一个随机的颜色,给定一个特定的种子数-快。 给定相同的ID两次,应该返回相同的颜色。在
我这样做了:
def id_to_random_color(number):
random_bytes = hashlib.sha1(bytes(number)).digest()
return [int(random_bytes[-1]) / 255, int(random_bytes[-2]) / 255, int(random_bytes[-3]) / 255, 1.0]
问题是,多次计算数字的sha1总的来说非常慢。(我使用这个函数大约10万次)
编辑:我使用散列函数的原因是,我希望对接近的数字使用不同的颜色
例如id_to_random_color(7)
应该与{
你没有提到
number
的范围。它必须是非负整数,否则bytes(number)
将失败。(顺便说一句,该函数返回一个由number
个零字节组成的bytes
字符串,如果number
很大,它将占用大量的RAM)。我假设number
至少是24位来覆盖24位RGB颜色空间。在为此目的使用加密哈希函数是过分的。因此,},所以我们需要做类似
hashlib
函数非常快,因为它们是用C语言编写的。我们可以使用内置的函数,但是对于机器大小的整数,hash(n)
只返回{hash((n, n))
的操作来获得随机输出。然而,做这种事情的结果并不是特别随机的:hash
是为哈希表工作而设计的,而不是我们这里想要的那种置乱。在为了生成随机的RGB值,我采用了Yann Collet的xxHash的混合算法。您可以在xxhash.c source code中查看该算法的C源代码。该算法速度相当快,具有良好的avalanching。Bret Mulvey写了一篇很好的关于hash mixing functions and the avalanche effect的介绍性文章。在
此函数适用于
^{pr2}$range(2**24)
中的n
,事实上,它的结果在整个range(2**32)
中是相当好的;它仍将在该范围之外给出有用的结果。为了在这里测试它,我将使用一个简化的版本,它将RGB值作为整数返回。第一个测试只显示n
中n
的RGB值。第二个测试生成25600个随机数并找到相应的RGB值。每个R、G和B值应该可以得到大约100次点击。在输出
计数器输出
您可能会注意到,
id_to_RGB
对于一个零输入返回所有的零。如果这是不需要的,您可以在开始处添加一个额外的混合步骤(也借用了xxHash)。在使用带有静态变量的简单随机数生成器可以提高性能:
更新:
^{pr2}$正如AndrewMcDowell在其评论中所说,如果输入在不连续的情况下重复,函数可能会返回不同的值。
以下是一个可能的解决方法:
进一步更新:
甚至可以使用相同的函数骨架来计算哈希:
尽管语法有点冗长,但是
else
语句提高了位性能,避免了随后的内存写入和读取(正如Jake在回答中所述)。在我会用字典快速索引已经生成的种子。在
相关问题 更多 >
编程相关推荐