我正在尝试计算在 Python 中成功猜测密码的可能性。例如,如果我们采用 10 个字符的小写密码(26**10 个可能的密码),并且每秒可以猜测 10 亿次,我们可以计算一小时内成功猜出密码的概率:
from scipy.stats import binom
(1 - binom.pmf(k=0, n=1000000000*3600, p=1 / 26**10))
这给我们的结果是0.02525515384826793
(即2.5%)。但是,当我们增加密码长度时(或更严格地说,当 p
接近于零时),这不起作用。例如,如果我们将密码长度增加到 12 个字符:
from scipy.stats import binom
(1 - binom.pmf(k=0, n=1000000000*3600, p=1 / 26**12))
那么返回的值只是 0.0
,这是不正确的 - 可能是由于 float 在某个时刻向下舍入为零。我如何计算以获得更准确的答案?
编辑:这是使用 SciPy 1.10.1 的。对最新版本(撰写本文时为 1.11.2)的测试给出了正确的值 - 因此看起来这是旧版本的问题。
最佳答案
我认为这是关于浮点运算的局限性,我也经常遇到这种局限性(即浮点溢出)。
您可以使用 mpmath 库,它提供任意精度算术:
from mpmath import mp
mp.dps = 50 # Set the desired precision (adjust as needed)
total_passwords = 26**12
guesses_per_second = 1000000000
seconds_in_an_hour = 3600
p = mp.mpf(1) / mp.mpf(total_passwords)
n = mp.mpf(guesses_per_second) * mp.mpf(seconds_in_an_hour)
probability = 1 - mp.power(1 - p, n)
print(float(probability))
额外注意:即使您只是使用 0.2 或 76.5 这样看似无害的数字, float 也会失去精度。对相同数据进行大量浮点运算时应格外小心,因为错误可能会很快累积。
我希望这能有所帮助。
关于python - 如何在Python中计算非常小的数字的二项式概率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77043946/