我正在尝试编写一个python脚本来测试/ dev / random的随机性,但我不能让它给我任何数字。我的代码看起来像这样
以open(“/ dev / random”,“rb”)作为文件: print f.read(10)
我认为应该从/ dev / random打印出10个字节,但不是数字,而是打印出奇怪的字符(非标准字母,没有数字)。知道我做错了吗?
谢谢!
答案 0 :(得分:10)
Python有一个内置函数(也可以在其他操作系统上使用适当的方法)...
import os
print os.urandom(10)
# '\xf1\x11xJOl\xab\xcc\xf0\xfd'
来自http://docs.python.org/2/library/os.html#os.urandom
的文档此函数返回来自OS特定随机源的随机字节。对于加密应用程序,返回的数据应该是不可预测的,尽管其确切的质量取决于操作系统的实现。在类UNIX系统上,这将查询/ dev / urandom,在Windows上,它将使用CryptGenRandom。如果未找到随机源,则将引发NotImplementedError。
如果您希望这些字节为数字,则可以通过以下方式进行转换:
>>> rand = os.urandom(10)
>>> int(rand.encode('hex'), 16)
1138412584848598544216317L
虽然/dev/random
和/dev/urandom
略有不同,但您可以使用现有的.read()
操作,只需对int
转换,如果差异对您很重要。
答案 1 :(得分:9)
你得到10个字节。 Python不会自动将它们变成数字。
我建议您以4的倍数获取字节,然后将它们转换为32位无符号整数,然后将它们缩放到您需要的任何值。
编辑:旧代码显示了这个想法,但很少分为功能。这是相同的基本想法,但现在可以方便地打包成函数。import os
import struct
_random_source = open("/dev/random", "rb")
def random_bytes(len):
return _random_source.read(len)
def unpack_uint32(bytes):
tup = struct.unpack("I", bytes)
return tup[0]
UINT32_MAX = 0xffffffff
def randint(low, high):
"""
Return a random integer in the range [low, high], including
both endpoints.
"""
n = (high - low) + 1
assert n >= 1
scale_factor = n / float(UINT32_MAX + 1)
random_uint32 = unpack_uint32(random_bytes(4))
result = int(scale_factor * random_uint32) + low
return result
def randint_gen(low, high, count):
"""
Generator that yields random integers in the range [low, high],
including both endpoints.
"""
n = (high - low) + 1
assert n >= 1
scale_factor = n / float(UINT32_MAX + 1)
for _ in range(count):
random_uint32 = unpack_uint32(random_bytes(4))
result = int(scale_factor * random_uint32) + low
yield result
if __name__ == "__main__":
# roll 3 dice individually with randint()
result = [randint(1, 6) for _ in range(3)]
print(result)
# roll 3 dice more efficiently with randint_gen()
print(list(randint_gen(1, 6, 3)))
答案 2 :(得分:1)
它打印随机字符,因此只需使用ord()
函数将它们转换为int。类似的东西:
with open("/dev/random", 'rb') as file: print [ord(x) for x in file.read(10)]
这将打印一个从0到255的10个随机整数的列表。(我得到了:[117, 211, 225, 24, 134, 145, 51, 234, 153, 89]
)。
答案 3 :(得分:0)
在Python 3.2及更高版本中,以下内容比旧答案中的解决方案更短,可能更快:
with open("/dev/random", 'rb') as f:
print(int.from_bytes(f.read(10), 'big'))
这会打印一个80位数字(范围为0到2 ^ 80-1)。