python随机模块 无范围,Python随机函数不使用随机模块

I need to write the function -

random_number(minimum,maximum)

Without using the random module and I did this:

import time

def random_number(minimum,maximum):

now = str(time.clock())

rnd = float(now[::-1][:3:])/1000

return minimum + rnd*(maximum-minimum)

I am not sure this is fine.. is there a known way to do it with the time?

解决方案

The thing is I need to do something that somehow uses the time

You could generate randomness based on a 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

Once you have getrandbits(k), it is straigforward to get a random integer in range [a, b], including both end points. 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

Example, to generate 20 random numbers from 10 to 110 including:

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

Output:

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

If getrandbits(k) returns k random bits then randint(a, b) should work as is (no skew due to modulo, etc).

To test the quality of getrandbits(k), dieharder utility could be used:

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

where random-from-time.py generates infinite (random) binary stream:

#!/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)

where getrandbits(k) is defined above.

The above assumes that you are not allowed to use os.urandom() or ssl.RAND_bytes(), or some known PRNG algorithm such as Mersenne Twister to implement getrandbits(k).

getrandbits(n) implemented using "time.sleep() + time.clock()" fails dieharder tests (too many to be a coincidence).

The idea is still sound: a clock drift may be used as a source of randomness (entropy) but you can't use it directly (the distribution is not uniform and/or some bits are dependent); the bits could be passed as a seed to a PRNG that accepts an arbitrary entropy source instead. See "Mixing" section.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值