2015-09-21 20 views
8

Ho osservato domande simili su come generare numeri casuali in python. Esempio: Similar Question - ma non ho il problema che la funzione random restituisce sempre gli stessi valori.random.choice() restituisce lo stesso valore allo stesso secondo, come si evita?

Il mio generatore casuale funziona bene, il problema è che restituisce lo stesso valore quando si chiama la funzione a, cosa penso, lo stesso secondo che non è desiderabile.

Il mio codice è simile al seguente

def getRandomID(): 
    token = '' 
    letters = "abcdefghiklmnopqrstuvwwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 
    for i in range(1,36): 
     token = token + random.choice(letters) 
    return token 

Come ho detto questa funzione restituisce valori diversi quando vengono chiamati in su tempi diversi, ma restituisce lo stesso valore quando si chiama la funzione allo stesso tempo. Come evito questo problema?

Io uso questa funzione in un server back-end per generare ID univoci per gli utenti in front-end da inserire in un database in modo da non poter controllare gli intervalli di tempo quando ciò accade. Devo avere token casuali per mappare gli utenti nel database in modo da poterli inserire correttamente con i queuumum nel database.

+0

come restituisce lo stesso id quando viene chiamato da due utenti contemporaneamente ?? – Hackaholic

+9

Suggerisco di usare 'uuid' per generare ID utente casuali. – hjpotter92

+0

Hackaholic - esattamente, restituisce lo stesso "token" che è la stessa stringa di randomlett quando viene chiamato da due utenti. –

risposta

4

Si potrebbe migliorare la situazione utilizzando random.SystemRandom() come segue:

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() 

Questo tenta di utilizzare la funzione di os.urandom() che genera numeri casuali da fonti fornite dal sistema operativo.

+0

Penso che questo abbia risolto il problema a prima vista. Proverò a eseguire un test su scala più grande in cui posso confermare che la soluzione funziona! –

1
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 

questo script nel 3 ° prova di 10 milioni di ids di nuovo li hanno resi tutti unici

cambiare ciclo for per elencare la comprensione ha velocizzare un po '.

>>> listt = getRandomID(10000000) 
>>> print(len(listt)) 
10000000 

>>> sofIds = set(listt) 
>>> print(len(sofIds)) 
10000000 

questo script utilizza permutazioni con ripetizione: 62 a 36, ​​ al numero teoricamente totale di IDS è abbastanza grande è pow (62,36)

59720078628458064562952815512525677808980550940333281573339136 
+0

Ti preghiamo di considerare la modifica del tuo post per aggiungere ulteriori spiegazioni su cosa fa il tuo codice e perché risolverà il problema. Una risposta che per lo più contiene solo codice (anche se funziona) di solito non aiuta l'OP a capire il loro problema. Da quello che posso vedere, questo è ridondante anche se questo è ciò che (credo) che Python normalmente usa come base per il suo seme. E anche se non lo è, questo fornirà sempre lo stesso seme allo stesso tempo, risultando nello stesso output. – SuperBiasedMan

+0

Non si desidera chiamare 'random.seed' dalla routine che genera i numeri casuali. Occorrerà (occasionalmente, non deterministicamente) finire con lo stesso valore che ritorna da 'datetime.now' nelle chiamate successive, il che causerà' random.choice 'per restituire sequenze identiche. –

1

Un'altra opzione potrebbe essere quella di aggiornare il seme con il risultato precedente per ottenere una sequenza pseudocasuale. Un'opzione sarebbe il risultato XOR di old_seed o solo il risultato.