2015-06-01 17 views
18

A partire da Python 3.3, l'algoritmo di hashing è in modo non deterministico salted per evitare un determinato tipo di attacco. Questo è utile per i server Web, ma è un problema quando si tenta di eseguire il debug di un programma: Ogni volta che eseguo il mio script, i contenuti di dettato vengono ripetuti in un ordine diverso.Disabilitare la randomizzazione dell'hash dal programma python

Alcune versioni precedenti di Python avevano una bandiera -R per consentendo hash randomizzazione, ma ora che è il comportamento di default, la bandiera non è stato sostituito dal suo opposto. randomizzazione può essere disabilitato impostando la variabile di ambiente PYTHONHASHSEED:

PYTHONHASHSEED

Se questa variabile non è impostata o impostata casuale, un valore casuale viene utilizzato per inizializzare le hash di str, byte e oggetti datetime.
Se PYTHONHASHSEED è impostato su un valore intero, viene utilizzato come seme fisso per generare l'hash() dei tipi coperti dalla casualità dell'hash.

Il problema è che questa variabile deve essere impostata prima di avviare il processo python. Ho provato a impostarlo con os.putenv() o in os.environ, ma questi sembrano non avere alcun effetto sul metodo di hashing. Questo non è troppo sorprendente: non mi aspetterei che Python verifichi l'ambiente prima di ogni singolo set o ricerca del dizionario! Quindi, la domanda rimane:

C'è un modo per un programma python di disabilitare la propria randomizzazione dell'hash?

+0

Avrebbe dovuto accadere prima viene eseguito alcun codice Python vero e proprio; a quel punto, troppe stringhe sono state sottoposte a hash e collocate in elementi come type e module '__dict__'s. – user2357112

+0

Ho pensato lo stesso; ma spero che qualcuno che ne sa di più possa commentare. – alexis

+0

Questi sono i commit rilevanti: [f4b7ecf8a5f8] (https://hg.python.org/cpython/rev/f4b7ecf8a5f8) e [6b7704fe1be1] (https://hg.python.org/cpython/rev/6b7704fe1be1) - gettare uno sguardo attraverso di esso non vedo immediatamente una soluzione, ma è un punto di partenza. – dimo414

risposta

11

Sospetto che non sia possibile, sfortunatamente. Guardando test_hash.py la classe HashRandomizationTests e i suoi discendenti sono stati aggiunti nello commit that introduced this behavior. Esaminano il comportamento di hashing modificando l'ambiente e avviando un nuovo processo con PYTHONHASHSEED impostato in modo esplicito. Potresti provare a copiare quel modello, forse.

Ho anche appena notato che hai detto "Ogni volta che corro il mio script, il contenuto dict sono iterati in un ordine diverso". - Suppongo che tu sei a conoscenza di collections.OrderedDict, giusto? Questo è il modo normale per ottenere l'iterazione hash affidabile.


Se siete disposti a impostare il valore nel vostro ambiente di shell, si potrebbe anche solo avvolgere la chiamata pitone in uno script bash, per esempio

#! /bin/bash 
export PYTHONHASHSEED=0 

# call your python program here 

Questo evita di dover manipolare l'intero ambiente, a patto che tu stia bene con uno script di wrapper.

O anche solo passare il valore sulla riga di comando:

$ PYTHONHASHSEED=0 python YOURSCRIPT.py 
+1

Grazie, questa è un'indicazione abbastanza forte.E un buon consiglio per il respawning - sebbene al di là della bruttezza, ci sono contesti in cui non è pratico (ad esempio, se si esegue in un notebook ipython servito da un "kernel" remoto). Immagino di poterlo impostare su log-in per il mio ambiente ... Non ho intenzione di farlo da solo. – alexis

Problemi correlati