问题
I have been looking at similar questions regarding how to generate random numbers in python. Example: Similar Question - but i do not have the problem that the randomfunction returns same values every time.
My random generator works fine, the problem is that it returns the same value when calling the function at, what I think, the same second which is undesireable.
My code looks like this
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1,36):
token = token + random.choice(letters)
return token
As I mentioned this function returns different values when being called at on different times but returns the same value when calling the function at the same time. How do I avoid this problem?
I use this function in a back-end-server to generate unique IDs for users in front-end to insert in a database so I cannot control the time intervals when this happens. I must have random tokens to map the users in the database to be able to insert them correctly with queuenumbers in the database.
回答1:
You could possibly improve matters by using random.SystemRandom()
as follows:
import random
sys_random = random.SystemRandom()
def getRandomID():
token = ''
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
for i in range(1, 36):
token = token + sys_random.choice(letters)
return token
print(getRandomID())
This attempts to use the os.urandom()
function which generates random numbers from sources provided by the operating system. The .choices() function could also be used to return a list of choices in a single call, avoiding the string concatenation:
import random
sys_random = random.SystemRandom()
def getRandomID():
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
return ''.join(sys_random.choices(letters, k=35))
print(getRandomID())
回答2:
def getRandomID(n):
import datetime
import random
random.seed(datetime.datetime.now())
letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
idList = [ ''.join([random.choice(letters) for j in range(1,36)]) for i in range(n)]
return idList
this script in the 3rd test of 10 million ids again have made them all unique
changing for loop to list comprehension did speedup quite a bit.
>>> listt = getRandomID(10000000)
>>> print(len(listt))
10000000
>>> setOfIds = set(listt)
>>> print(len(setOfIds))
10000000
this script uses permutations with repetition: 62 choose 35, to theoretically total number of ids is quite big it is pow(62,35)
541638008296341754635824011376225346986572413939634062667808768
回答3:
Another option would be to update the seed with the previous result to get a pseudorandom sequence. An option would be old_seed XOR result or just the result.
来源:https://stackoverflow.com/questions/32692158/random-choice-returns-same-value-at-the-same-second-how-does-one-avoid-it