2009-05-03 15 views

Odpowiedz

23

Można użyć uuid library tak:

 
import uuid 
my_id = uuid.uuid1() # or uuid.uuid4() 
+1

Tego właśnie szukałem! – Alex

+5

Ale to nie jest bardzo losowe. – Gumbo

+0

@Gumbo: proszę opracować? – saffsd

1

może być tak proste jak tworzenie liczb losowych. Oczywiście będziesz musiał przechowywać identyfikatory sesji w bazie danych lub coś takiego i sprawdzać każdą wygenerowaną przez siebie, aby upewnić się, że nie jest ona duplikatem, ale szanse są takie, że nigdy nie będą, jeśli liczby są wystarczająco duże.

+0

Dokładnie, stąd moje rozwiązanie: http://stackoverflow.com/questions/817882/unique-session-id-in-python/818040#818040 –

21
import os, base64 
def generate_session(): 
    return base64.b64encode(os.urandom(16)) 
+0

dlaczego downmod? –

+1

Ja duno, ale wydaje się, że to prawidłowe rozwiązanie. Radzę jednak usunąć pasek "==", a także dołączyć sygnaturę czasową, aby zmniejszyć ryzyko kolizji. – Unknown

+1

Szansa na kolizję po 4 miliardach iteracji wynosi 1 na 8 miliardów.Jeśli chcę zmniejszyć szansę kolizji, mogę po prostu zwiększyć liczbę bitów, tj. Os.urandom (32). I nie rozumiem, co powinno się rozebrać na końcowym "==". –

1

Do czego służy sesja? Aplikacja internetowa? Możesz spojrzeć na the beaker module. Jest to domyślny moduł do obsługi sesji w Pylons.

73

UPDATE: 2016-12-21

Wiele działo się w ciągu ostatnich ~ 5yrs. /dev/urandom został zaktualizowany i jest obecnie uważany za źródło losowości o wysokiej entropii dla współczesnych jąder i dystrybucji Linuksa. W ostatnim 6mo widzieliśmy głód entropii na jądrze Linux 3.19 za pomocą Ubuntu, więc nie sądzę, aby problem ten został "rozwiązany", ale wystarczająco trudno jest uzyskać losowość o niskiej entropii, gdy żąda się dowolnej ilości losowości z systemu operacyjnego.


Nienawidzę tego mówić, ale żaden z innych rozwiązań zamieszczone tutaj są prawidłowe w odniesieniu do bycia „bezpieczny identyfikator sesji.”

# pip install M2Crypto 
import base64, M2Crypto 
def generate_session_id(num_bytes = 16): 
    return base64.b64encode(M2Crypto.m2.rand_bytes(num_bytes)) 

Ani uuid() lub os.urandom() są dobrym wyborem do generowania identyfikatorów sesji. Oba mogą generować wyniki losowe, ale losowe nie oznacza, że ​​jest bezpieczne z powodu złej entropii. Zobacz "How to Crack a Linear Congruential Generator" autorstwa Haldir lub NIST's resources on Random Number Generation. Jeśli nadal chcesz używać UUID, a następnie użyj UUID, które zostały wygenerowane przy dobrej początkowej liczby losowej:

import uuid, M2Crypto 
uuid.UUID(bytes = M2Crypto.m2.rand_bytes(num_bytes))) 
# UUID('5e85edc4-7078-d214-e773-f8caae16fe6c') 

czyli M2Crypto jest jak pojawia

# pip install pyOpenSSL 
import uuid, OpenSSL 
uuid.UUID(bytes = OpenSSL.rand.bytes(16)) 
# UUID('c9bf635f-b0cc-d278-a2c5-01eaae654461') 

najlepiej OpenSSL API w Pythonie atm pyOpenSSL być utrzymywane tylko w celu obsługi starszych aplikacji.

+0

Te cytaty dotyczące problemów z UUID są pomocne. Dzięki za zamieszczenie tego. Pytanie: Jak myślisz, jaki jest najlepszy sposób generowania identyfikatora sesji? Szczególnie w przypadku wad, które przytaczacie w implementacjach UUID, jak byście to zrobili inaczej? Piszę coś takiego teraz i próbuję wymyślić najlepsze podejście. Musi także być odporny na awarie - np. Nie może być zależny od połączenia z serwerem bazy danych. – ratsbane

+0

Każdy z powyższych przykładów zadziała. Kluczem jest użycie dobrego generatora liczb losowych, który jest wypełniony "kryptograficznie wystarczającą entropią". Poza estetyką i rozmiarem reprezentacji, nie ma różnicy między kodowaniem wystarczająco losowej wartości jako łańcucha "Base64" lub "UUID", a nawet łańcucha zakodowanego w postaci szesnastkowej. Do każdego z nich. Osobiście preferuję base64 ze względu na wielkość. – Sean

+0

Dzięki. To wydaje się być dobre. Napisałem to dziś po południu z – ratsbane

Powiązane problemy