Python随机函数,不使用随机模块

问题描述 投票:1回答:4

我需要编写函数 -

random_number(minimum,maximum)

不使用随机模块,我这样做:

import time

def random_number(minimum,maximum):
    now = str(time.clock())
    rnd = float(now[::-1][:3:])/1000
    return minimum + rnd*(maximum-minimum)

我不确定这是好的..有没有一种已知的方法与时间一起做?

python function random time
4个回答
5
投票

问题是我需要做一些以某种方式使用时间的东西

你可以根据clock drift生成随机性:

import struct
import time

def lastbit(f):
    return struct.pack('!f', f)[-1] & 1

def getrandbits(k):
    "Return k random bits using a relative drift of two clocks."
    # assume time.sleep() and time.clock() use different clocks
    # though it might work even if they use the same clock
    #XXX it does not produce "good" random bits, see below for details
    result = 0
    for _ in range(k):
        time.sleep(0)
        result <<= 1
        result |= lastbit(time.clock())
    return result

一旦你有getrandbits(k),在范围[a,b]中得到一个随机整数是很困难的,包括两个终点。 Based on CPython Lib/random.py

def randint(a, b):
    "Return random integer in range [a, b], including both end points."
    return a + randbelow(b - a + 1)

def randbelow(n):
    "Return a random int in the range [0,n).  Raises ValueError if n<=0."
    # from Lib/random.py
    if n <= 0:
       raise ValueError
    k = n.bit_length()  # don't use (n-1) here because n can be 1
    r = getrandbits(k)          # 0 <= r < 2**k
    while r >= n: # avoid skew
        r = getrandbits(k)
    return r

例如,从10到110生成20个随机数,包括:

print(*[randint(10, 110) for _ in range(20)])

输出:

11 76 66 58 107 102 73 81 16 58 43 107 108 98 17 58 18 107 107 77

如果getrandbits(k)返回k随机位,那么randint(a, b)应该按原样工作(由于模数等没有偏斜)。

为了测试getrandbits(k)的质量,可以使用dieharder实用程序:

$ python3 random-from-time.py | dieharder -a -g 200

其中random-from-time.py生成无限(随机)二进制流:

#!/usr/bin/env python3

def write_random_binary_stream(write):
    while True:
        write(getrandbits(32).to_bytes(4, 'big'))

if __name__ == "__main__":
    import sys
    write_random_binary_stream(sys.stdout.buffer.write)

其中getrandbits(k)定义如上。


以上假设您不允许使用os.urandom()ssl.RAND_bytes(),或某些已知的PRNG算法(如Mersenne Twister)来实现getrandbits(k)


使用“getrandbits(n) + time.sleep()”实施的time.clock()未通过dieharder测试(太多不巧合)。

这个想法仍然是合理的:时钟漂移可以用作随机源(熵),但你不能直接使用它(分布不均匀和/或某些比特依赖);这些比特可以作为种子传递给接受任意熵源的PRNG。见"Mixing" section


2
投票

您是否可以在某些特殊文件中读取随机数据?在Linux下,文件`/ dev / urandom'提供了获取随机字节的便捷方法。你可以写:

import struct
f = open("/dev/urandom","r")
n = struct.unpack("i",f.read(4))[0]

但是这不适用于Windows。


0
投票

使用API​​?如果允许的话。

import urllib2

def get_random(x,y):
    url = 'http://www.random.org/integers/?num=1&min=[min]&max=[max]&col=1&base=10&format=plain&rnd=new'
    url = url.replace("[min]", str(x))  
    url = url.replace("[max]", str(y))  
    response = urllib2.urlopen(url)
    num = response.read()
    return num.strip()

print get_random(1,1000)

0
投票

想法是使用时间模块获得0到1之间的数字并使用它来获得范围内的数字。以下将在20和60范围内随机打印20个数字

from time import time

def time_random():
 return time() - float(str(time()).split('.')[0])

def gen_random_range(min, max):
 return int(time_random() * (max - min) + min)

if __name__ == '__main__':
 for i in range(20):
     print gen_random_range(20,60)
© www.soinside.com 2019 - 2024. All rights reserved.