Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成随机函数(与随机数相反)_Python_Algorithm_Hash_Random - Fatal编程技术网

Python 生成随机函数(与随机数相反)

Python 生成随机函数(与随机数相反),python,algorithm,hash,random,Python,Algorithm,Hash,Random,我想创建一个函数,它接受一个字符串并返回一个介于0和1之间的数字。当给定相同的字符串时,函数应始终返回相同的数字,但结果不应有可识别的模式。任何一大组输入字符串的输出数都应该遵循统一的分布 此外,我需要生成多个这样的函数,即当给定字符串“abc”时,函数A可能始终返回0.593927,而函数B始终返回0.0162524。我需要它是快速的(用于数值模拟),并且有相当好的统计数据 我正在使用Python,并将满足于回答“这是一个使用Python库实现它的简单方法”或“这是一个您可以实现的算法”。如果

我想创建一个函数,它接受一个字符串并返回一个介于0和1之间的数字。当给定相同的字符串时,函数应始终返回相同的数字,但结果不应有可识别的模式。任何一大组输入字符串的输出数都应该遵循统一的分布

此外,我需要生成多个这样的函数,即当给定字符串“abc”时,函数A可能始终返回0.593927,而函数B始终返回0.0162524。我需要它是快速的(用于数值模拟),并且有相当好的统计数据

我正在使用Python,并将满足于回答“这是一个使用Python库实现它的简单方法”或“这是一个您可以实现的算法”。如果在Python中没有快速实现的方法,我将改为使用C

我意识到以下两种方法中的任何一种都会起作用,但它们都有缺点,这让我想寻找一种更优雅的解决方案

  • 存储字典
    我可以在每次给我一个新字符串时计算一个新的随机数,并将其存储在字典中,以便在再次收到相同的字符串时检索然而,我的应用程序可能会生成大量只出现一次的字符串,这最终将导致必须在内存中存储一个非常大的字典。这也使得重复性更加困难,因为即使我使用相同的种子,如果我以不同的顺序接收相同的字符串,我也会生成不同的函数。出于这些原因,最好是“在运行中”一致地计算随机数

  • 使用散列函数
    我可以对字符串调用一个哈希函数,然后将结果转换成一个数字。例如,生成多个函数的问题可以通过向每个输入字符串添加“种子”字符串来解决然而,我一直在努力找到一个具有适当速度和统计信息的哈希函数。Python内置的哈希很快,但依赖于实现,我不知道统计数据会有多好,因为它不是为这种目的而设计的。另一方面,我可以使用安全的散列算法,如md5,它将具有良好的统计数据,但这对我的应用程序来说太慢了。针对数据存储应用程序的散列函数通常比加密安全的函数(如md5)快得多,但它们的设计目的是避免冲突,而不是产生均匀分布的输出,并且并非所有情况下都是相同的

  • 关于散列函数的进一步说明


    为了说明避免冲突和产生一致结果的观点是不同的,请考虑使用Python的内置哈希函数:

    >>> hash("aaa") % 1000
    340
    >>> hash("aab") % 1000
    343
    >>> hash("aac") % 1000
    342
    >>> hash("aad") % 1000
    337
    >>> hash("aae") % 1000
    336
    >>> hash("aaf") % 1000
    339
    >>> hash("aag") % 1000
    338
    >>> hash("aah") % 1000
    349
    >>> hash("aai") % 1000
    348
    >>> hash("aaj") % 1000
    351
    >>> hash("aak") % 1000
    350
    
    上面的输出中没有冲突,但它们显然也不是均匀分布的,因为它们都在336和351之间,并且在第三个数字中也有一个确定的模式。我意识到我可能可以通过做
    (hash(“aaa”)/hash_MAX)*1000
    (假设我可以计算出
    hash_MAX
    应该是什么),来获得更好的统计数据,但这应该有助于说明,对一个好的hash函数的要求与我正在寻找的函数的要求不同

    有关问题的一些相关信息

    我不知道该算法需要处理的字符串是什么,因为字符串将由模拟生成,但以下情况可能是这样的:

  • 它们将有一个非常有限的字符集(可能只有4或5个不同的符号)

  • 将有许多独特或罕见的字符串和一些非常常见的不同长度的字符串

  • 字符串的长度没有上限,但短字符串可能比长字符串更常见。如果我从未见过一个超过100个字符的,我也不会感到惊讶,但我不确定。其中许多字符串只有一到三个字符,因此对于短字符串来说,算法的速度很快是很重要的。(但我想我可以使用查找表查找长度小于一定长度的字符串。)

  • 通常,这些字符串都有很大的公共子字符串-通常两个字符串的不同之处只是在开头或结尾附加了一个字符。当字符串相似时,算法不会给出相似的输出值,这一点很重要


  • Wikipedia上关于“哈希字符串”的文章中有一个算法

    或者,您可以只使用一些内置的哈希函数;在散列之前,每个随机函数都会在字符串前面加上一个随机(但固定)前缀。

    被认为具有非常好的冲突属性,这应该意味着结果分布均匀,而且速度也很快。将其放在Python扩展中应该很简单

    更一般地说,如果您发现一个函数在最小化哈希表冲突方面做得很好,并且具有所需的速度属性,那么只需要将32位或64位整数最终转换为浮点值。在web和其他地方有许多字符串哈希函数的源代码。首先,检查一下

    添加


    另一件值得尝试的事情是,首先使用快速的1-1算法(如RC4)加密字符串(不安全,但仍然接近伪随机),然后在密文上运行一个简单的散列(h=h+a*c[i]+b)。RC4密钥是唯一标识符。

    尝试使用指纹,如拉宾指纹。
    .

    如果选择N位指纹,只需将结果除以2^N即可

    指纹是一种哈希函数,通常对计算机来说非常快(与li相比)