2014-04-24 12 views
9

In 64 bit di Python 2.7.6 questo è vero, ma in 32 bit Python 2.7.3 è falso:Come si usano le stringhe di hash Python 2.7.3 per seminare generatori di numeri casuali?

random.Random(hash("a")).random() == random.Random("a").random() 

Così come Python 2.7.3 stringhe hash utilizzato per seminare generatori di numeri casuali?

+2

Python * è * open source - si può solo leggere il codice. –

+0

Inoltre, sarebbe utile provare anche in Python 2.7.6 a 32 bit e Python 2.7.3 a 64 bit per limitare se la differenza è tra 2.7.3 e 2.7.6 o 32-bit e 64-bit. E quale sistema operativo è questo? –

+0

Sospetto che varia sia tra piattaforme e architetture di compilazione, ma anche tra stringhe specifiche. Supponendo che l'hash di Python sia ben distribuito, dovrebbe funzionare per circa la metà degli oggetti con cui lo si prova e fallire per metà. – Blckknght

risposta

9

è perché su 32 bit hash("a") è un numero negativo (a causa della dimensione del tipo di piattaforma lunga) ei moduli casuali si comportano in modo diverso.

Il seme modulo random() funzione:

  • passaggio int long userà PyNumber_Absolute() che è abs()
  • passaggio di un oggetto (una stringa) userà PyLong_FromUnsignedLong((unsigned long)hash)

segno bit troncamento e addominali danno un risultato diverso

ad es .:

  • abs(-10) = 10
  • ((unsigned long) -10) = 4294967286
+1

Questa è la risposta giusta. Vale la pena notare che [un commento sopra il codice che fa questo] (http://hg.python.org/cpython/file/0c8a7299c7e3/Modules/_randommodule.c#l231) in Python 2 dice erroneamente che prende il valore assoluto in entrambi i casi. In Python 3, [il commento è stato corretto] (http://hg.python.org/cpython/file/e159cb0d955b/Modules/_randommodule.c#l228) per descrivere correttamente cosa fa per i non interi (lanciare il segno valore hash a uno senza segno, che equivale ad aggiungere 'sys.maxsize' a qualsiasi valore negativo). – Blckknght

Problemi correlati