Losowe ciągi znaków w Pythonie

96

Jak utworzyć losowy ciąg w Pythonie?

Potrzebowałem liczby, a następnie powtarzanie postaci, aż skończysz, to jest to, co stworzyłem

def random_id(length):
    number = '0123456789'
    alpha = 'abcdefghijklmnopqrstuvwxyz'
    id = ''
    for i in range(0,length,2):
        id += random.choice(number)
        id += random.choice(alpha)
    return id
RHicke
źródło
Podaj więcej szczegółów i podaj kilka przykładów tego, czego szukasz.
słodki
możliwy duplikat ciągów losowych w Pythonie 2.6 (Czy to w porządku?)
Ślimak mechaniczny

Odpowiedzi:

224

Generowanie ciągów z (na przykład) małych liter:

import random, string

def randomword(length):
   letters = string.ascii_lowercase
   return ''.join(random.choice(letters) for i in range(length))

Wyniki:

>>> randomword(10)
'vxnxikmhdc'
>>> randomword(10)
'ytqhdohksy'
sth
źródło
3
Jak dotąd najlepsza odpowiedź. Chociaż użyłbym randomword(length, source_alpha=string.lowercase)i xrange(length).
Hank Gay
1
Zauważ, że chociaż jest to bardzo dobra odpowiedź, PO zmodyfikował pytanie, aby je unieważnić. I udzielić własnej odpowiedzi.
Blair Conrad
29
Aby string.ascii_lowercase
zapewnić
@BlairConrad: Powiedziałbym, że pytanie było zbyt szerokie, np. os.urandom(length)Odpowiada na oryginalne pytanie, a @sth niepoprawnie czytał w myślach OP.
jfs
2
Od Pythona 3.6 random.choicesbyłoby szybsze.
IanS
59

Ponieważ to pytanie jest dość, hm, przypadkowe, to może Ci pomóc:

>>> import uuid
>>> print uuid.uuid4()
58fe9784-f60a-42bc-aa94-eb8f1a7e5c17
Brandon
źródło
6
W wielu przypadkach losowość nie jest tak naprawdę wymagana. Raczej wszystko, czego naprawdę potrzebujesz, jest wyjątkowe.
Chase Seibert
1
możesz użyć, str(uuid.uuid4())jeśli chcesz użyć go jako ciągu.
Swagatika,
2
str(uuid.uuid4()).split("-")[0]Wyjście:'4bcb6450'
Vlad Gulin
Słuszna uwaga, Vlad. Przez coś dłuższego działa również .join (str (uuid.uuid4 ()). Split ('-')). Wyjście: „00db8a458c71415c9a263ff08667dd93”
Brandon,
35
>>> import random
>>> import string
>>> s=string.lowercase+string.digits
>>> ''.join(random.sample(s,10))
'jw72qidagk
ghostdog74
źródło
Schludny! Właściwie używam tego teraz do generatora losowych haseł! Dzięki!
chandsie
13
random.sample pobierze unikalne znaki z s, tj. znaki w haśle nigdy się nie powtórzą. Jest to znacznie mniej bezpieczne niż użycie random.choice, jak w zaakceptowanej odpowiedzi.
Nick Zalutskiy
3
@NickZalutskiy: też random.choicenie jest bezpieczny. Użyj random.SystemRandom().choice()lub użyj os.urandom()bezpośrednio .
jfs
1
OSTRZEŻENIE! zwróć uwagę na dwa powyższe komentarze. random.sample zwraca unikalne próbki. znaki nie są powtarzane. więc zwracany ciąg jest mniej losowy. W przypadku większych łańcuchów błąd: „ValueError: próbka większa niż populacja”.
gaoithe
1
W Pythonie 3 lowercasenależy go zastąpićascii_lowercase
Attaque
18

Odpowiedź na pierwotne pytanie:

os.urandom(n)

Cytat z: http://docs.python.org/2/library/os.html

Zwraca ciąg n losowych bajtów odpowiednich do użytku kryptograficznego.

Ta funkcja zwraca losowe bajty ze źródła losowości specyficznego dla systemu operacyjnego. Zwracane dane powinny być wystarczająco nieprzewidywalne dla aplikacji kryptograficznych, chociaż ich dokładna jakość zależy od implementacji systemu operacyjnego. W systemie podobnym do UNIX spowoduje to zapytanie / dev / urandom, aw systemie Windows użyje CryptGenRandom. Jeśli nie zostanie znalezione źródło losowości, zostanie zgłoszony błąd NotImplementedError.

Aby uzyskać łatwy w użyciu interfejs do generatora liczb losowych dostarczonego przez Twoją platformę, zobacz random.SystemRandom.

Tomek
źródło
5

Możesz budować losowe postacie ascii, takie jak:

import random
print chr(random.randint(0,255))

A następnie zbuduj dłuższy ciąg, taki jak:

len = 50
print ''.join( [chr(random.randint(0,255)) for i in xrange(0,len)] )
Ross Rogers
źródło
1
Po co używać formatowania ciągów? ''.join(map(chr, random.randint(0,256) for _ in xrange(len)))
Chris Lutz,
5

Tak naprawdę nie powiedziałeś zbyt wiele o tym, jakiego rodzaju losowego ciągu potrzebujesz. Ale w każdym razie powinieneś zajrzeć do randommodułu.

Poniżej wklejono bardzo proste rozwiązanie.

import random

def randstring(length=10):
    valid_letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return ''.join((random.choice(valid_letters) for i in xrange(length)))

print randstring()
print randstring(20)
MAK
źródło
fyi możesz pominąć najbardziej zewnętrzny zestaw paren w instrukcji return.
rekurencyjne
4

Czasami chciałem przypadkowych ciągów, które są na wpół wymawiane i zapadają w pamięć.

import random

def randomWord(length=5):
    consonants = "bcdfghjklmnpqrstvwxyz"
    vowels = "aeiou"

    return "".join(random.choice((consonants, vowels)[i%2]) for i in range(length))

Następnie,

>>> randomWord()
nibit
>>> randomWord()
piber
>>> randomWord(10)
rubirikiro

Aby uniknąć 4-literowych słów, nie ustawiaj length 4.

Jim

Jim
źródło
3
random_name = lambda length: ''.join(random.sample(string.letters, length))

długość musi wynosić <= len (string.letters) = 53. przykład wyniku

   >>> [random_name(x) for x in range(1,20)]
['V', 'Rq', 'YtL', 'AmUF', 'loFdS', 'eNpRFy', 'iWFGtDz', 'ZTNgCvLA', 'fjUDXJvMP', 'EBrPcYKUvZ', 'GmxPKCnbfih', 'nSiNmCRktdWZ', 'VWKSsGwlBeXUr', 'i
stIFGTUlZqnav', 'bqfwgBhyTJMUEzF', 'VLXlPiQnhptZyoHq', 'BXWATvwLCUcVesFfk', 'jLngHmTBtoOSsQlezV', 'JOUhklIwDBMFzrTCPub']
>>> 

Cieszyć się. ;)

Spouk
źródło
1

W python3.6+możesz skorzystać z secretsmodułu :

Moduł sekretów służy do generowania silnych kryptograficznie liczb losowych odpowiednich do zarządzania danymi, takimi jak hasła, uwierzytelnianie kont, tokeny bezpieczeństwa i powiązane sekrety.

W szczególności sekrety powinny być używane zamiast domyślnego generatora liczb pseudolosowych w module losowym, który jest przeznaczony do modelowania i symulacji, a nie do bezpieczeństwa lub kryptografii.

Testując generację 768bittokenów bezpieczeństwa znalazłem:

  • random.choices() - 0.000246sek
  • secrets.choice()- 0.003529sek

Te secretsmoduły są wolniejsze, ale poza testowanie go to, co powinno być w użyciu dla celów kryptograficznych:

import string, secrets

def random_string(size):        
        letters = string.ascii_lowercase+string.ascii_uppercase+string.digits            
        return ''.join(secrets.choice(letters) for i in range(size))

print(random_string(768))
Stuart Cardall
źródło
0

Ta funkcja generuje losowy ciąg składający się z wielkich i małych liter, cyfr, przekazuje separator długości, no_of_blocks, aby określić format ciągu

np .: len_sep = 4, no_of_blocks = 4 wygeneruje następujący wzorzec,

F4nQ-Vh5z-JKEC-WhuS

Gdzie separator długości doda „-” po 4 znakach

XXXX-

liczba bloków wygeneruje następujący wzór znaków jako ciąg

XXXX - XXXX - XXXX - XXXX

jeśli potrzebny jest jeden losowy ciąg, po prostu zachowaj zmienną no_of_blocks równą 1 i len_sep, aby określić długość losowego ciągu.

np: len_sep = 10, no_of_blocks = 1, wygeneruje następujący wzorzec tj. losowy ciąg o długości 10 ,

F01xgCdoDU

import random as r

def generate_random_string(len_sep, no_of_blocks):
    random_string = ''
    random_str_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    for i in range(0,len_sep*no_of_blocks):
        if i % len_sep == 0 and i != 0:
            random_string += '-'
        random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
    return random_string
Manoj Selvin
źródło
0
import random 
import string

def get_random_string(size):
    chars = string.ascii_lowercase+string.ascii_uppercase+string.digits
    ''.join(random.choice(chars) for _ in range(size))

print(get_random_string(20)

wyjście: FfxjmkyyLG5HvLeRudDS

Rakesh babu
źródło
-1

spróbuj zaimportować poniższy pakiet z losowego importu *

Yash chitroda
źródło
To w ogóle nie rozwiązuje problemu. Czy jest lepszy (pythonowy) sposób generowania tego wzorca losowo
drekbour