Random string generasi dengan huruf dan angka

Saya ingin menghasilkan sebuah string dari ukuran N.

Ini harus terdiri dari angka dan huruf besar huruf bahasa inggris seperti:

  • 6U1S75
  • 4Z4UKK
  • U911K4

Bagaimana saya bisa mencapai hal ini dalam pythonic cara?

Mengomentari pertanyaan (5)
Larutan

Jawaban dalam satu baris:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

atau bahkan lebih pendek mulai dengan Python 3.6 menggunakan acak.pilihan():

''.join(random.choices(string.ascii_uppercase + string.digits, k=N))

Kode-kode atau sandi yang lebih aman versi; lihat https://stackoverflow.com/a/23728630/2213647:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

Dalam rincian, dengan fungsi untuk selanjutnya digunakan kembali:

>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...    return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'

Bagaimana cara kerjanya ?

Kita impor string, sebuah modul yang berisi urutan umum karakter ASCII, dan random, sebuah modul yang berhubungan dengan generasi acak.

string.ascii_uppercase + string.digit hanya merangkai daftar karakter yang mewakili huruf ASCII karakter dan angka:

>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

Kemudian kita menggunakan daftar pemahaman untuk membuat daftar 'n' unsur-unsur:

>>> range(4) # range create a list of 'n' numbers
[0, 1, 2, 3]
>>> ['elem' for _ in range(4)] # we use range to create 4 times 'elem'
['elem', 'elem', 'elem', 'elem']

Dalam contoh di atas, kita menggunakan [ untuk membuat daftar, tapi kami don't dalam id_generator fungsi jadi Python doesn't membuat daftar dalam memori, tetapi menghasilkan unsur-unsur on the fly, one by one (lebih lanjut tentang ini di sini).

Bukannya meminta untuk membuat 'n' times string elem, kami akan meminta Python untuk membuat 'n' times karakter acak, diambil dari urutan karakter:

>>> random.choice("abcde")
'a'
>>> random.choice("abcde")
'd'
>>> random.choice("abcde")
'b'

Oleh karena itu acak.pilihan(karakter) untuk _ dalam jangkauan(size) benar-benar adalah membuat urutan ukuran karakter. Karakter yang secara acak diambil dari karakter:

>>> [random.choice('abcde') for _ in range(3)]
['a', 'b', 'b']
>>> [random.choice('abcde') for _ in range(3)]
['e', 'b', 'e']
>>> [random.choice('abcde') for _ in range(3)]
['d', 'a', 'c']

Maka kita hanya bergabung dengan mereka dengan string kosong sehingga urutan tersebut menjadi sebuah string:

>>> ''.join(['a', 'b', 'b'])
'abb'
>>> [random.choice('abcde') for _ in range(3)]
['d', 'c', 'b']
>>> ''.join(random.choice('abcde') for _ in range(3))
'dac'
Komentar (27)

Ini Stack Overflow quesion saat ini Google atas hasil untuk "random string Python". Saat ini beberapa jawabannya:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

Ini adalah metode yang sangat baik, tapi PRNG di acak tidak cryptographically aman. Saya berasumsi banyak orang meneliti pertanyaan ini akan ingin menghasilkan string acak untuk enkripsi atau password. Anda dapat melakukan ini dengan aman dengan membuat perubahan kecil di kode di atas:

''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(N))

Menggunakan acak.SystemRandom() bukan hanya acak menggunakan /dev/urandom pada *nix mesin dan CryptGenRandom() pada Windows. Ini adalah cryptographically aman PRNGs. Menggunakan acak.pilihan bukan acak.SystemRandom().pilihan dalam aplikasi yang membutuhkan aman PRNG bisa berpotensi menghancurkan, dan mengingat popularitas dari pertanyaan ini, saya yakin bahwa kesalahan telah dibuat berkali-kali sudah.

Jika anda're menggunakan python3.6 atau di atas, anda bisa menggunakan rahasia modul seperti yang disebutkan dalam MSeifert's jawaban:

''.join(secrets.choice(string.ascii_uppercase + string.digits) for _ in range(N))

Modul docs juga membahas cara mudah untuk menghasilkan aman token dan praktek-praktek terbaik.

Komentar (6)

Hanya menggunakan Python's builtin uuid:

Jika Uuid baik-baik saja untuk keperluan anda, menggunakan built-in uuid paket.

Salah Satu Solusi Baris:

impor uuid; uuid.uuid4().hex.upper()[0:6]

Di Kedalaman Versi:

Contoh:

import uuid
uuid.uuid4() #uuid4 => full random uuid
# Outputs something like: UUID('0172fc9a-1dac-4414-b88d-6b9a6feb91ea')

Jika anda perlu benar-benar anda format (misalnya, "6U1S75"), anda dapat melakukannya seperti ini:

import uuid

def my_random_string(string_length=10):
    """Returns a random string of length string_length."""
    random = str(uuid.uuid4()) # Convert UUID format to a Python string.
    random = random.upper() # Make all characters uppercase.
    random = random.replace("-","") # Remove the UUID '-'.
    return random[0:string_length] # Return the random string.

print(my_random_string(6)) # For example, D9E50C
Komentar (9)

Lebih sederhana, lebih cepat, tapi sedikit kurang cara acak adalah dengan menggunakan acak.sampel bukannya memilih setiap huruf secara terpisah, Jika n-pengulangan diperbolehkan, memperbesar secara acak dengan n kali misalnya

import random
import string

char_set = string.ascii_uppercase + string.digits
print ''.join(random.sample(char_set*6, 6))

Catatan: acak.sampel mencegah karakter reuse, mengalikan ukuran set karakter membuat beberapa pengulangan mungkin, tetapi mereka masih kurang mungkin kemudian mereka secara murni pilihan acak. Jika kita pergi untuk string dengan panjang 6, dan kita pilih 'X' sebagai karakter pertama, dalam pilihan contoh, peluang mendapatkan 'X' untuk kedua karakter yang sama seperti peluang mendapatkan 'X' sebagai karakter pertama. Di acak.contoh implementasi, peluang mendapatkan 'X' karena setiap karakter berikutnya hanya 6/7 kesempatan untuk mendapatkan ini sebagai karakter pertama

Komentar (10)
import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str adalah nilai acak seperti 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str adalah 'CEA8B32E00934AAEA8C005A35D85A5C0'

Komentar (4)

Lebih cepat, lebih mudah dan lebih fleksibel cara untuk melakukan ini adalah dengan menggunakan strgen modul (pip menginstal StringGenerator).

Menghasilkan 6 karakter string acak dengan huruf dan angka:

>>> from strgen import StringGenerator as SG
>>> SG("[\u\d]{6}").render()
u'YZI2CI'

Dapatkan daftar unik:

>>> SG("[\l\d]{10}").render_list(5,unique=True)
[u'xqqtmi1pOk', u'zmkWdUr63O', u'PGaGcPHrX2', u'6RZiUbkk2i', u'j9eIeeWgEF']

Guarantee satu "khusus" karakter dalam string:

>>> SG("[\l\d]{10}&[\p]").render()
u'jaYI0bcPG*0'

Acak HTML color:

>>> SG("#[\h]{6}").render()
u'#CEdFCa'

dll.

Kita perlu menyadari bahwa ini:

''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(N))

mungkin tidak memiliki digit (atau karakter huruf besar) di dalamnya.

strgen lebih cepat dalam pengembang-waktu dari setiap solusi di atas. Solusi dari Ignacio adalah yang tercepat run-time dan melakukan adalah jawaban yang tepat menggunakan Python Library Standar. Tapi anda tidak akan pernah menggunakannya dalam formulir itu. Anda akan ingin menggunakan SystemRandom (atau mundur jika tidak tersedia), pastikan diperlukan set karakter yang diwakili, menggunakan unicode (atau tidak), pastikan berturut-turut pemanggilan menghasilkan sebuah string unik, menggunakan subset dari salah satu string modul kelas karakter, dll. Ini semua membutuhkan banyak kode yang lebih dari pada jawaban yang diberikan. Berbagai upaya untuk menggeneralisasi solusi semua memiliki keterbatasan yang strgen memecahkan dengan lebih singkatnya dan daya ekspresif menggunakan template sederhana bahasa.

It's di PyPI:

pip install StringGenerator

Disclosure: saya'm penulis strgen modul.

Komentar (0)

Dari Python 3.6 pada anda harus menggunakan rahasia modul bila yang anda butuhkan untuk menjadi cryptographically secure bukan random modul (jika jawaban ini identik dengan salah satu dari @Ignacio Vazquez-Abrams):

from secrets import choice
import string

''.join([choice(string.ascii_uppercase + string.digits) for _ in range(N)])

Satu catatan tambahan: daftar-pemahaman lebih dalam kasus str.bergabung daripada menggunakan generator ekspresi!

Komentar (0)

Berdasarkan Tumpukan lain Overflow menjawab, Paling ringan cara untuk membuat sebuah string acak dan acak nomor heksadesimal, versi yang lebih baik dari jawaban yang diterima akan sama:

('%06x' % random.randrange(16**6)).upper()

jauh lebih cepat.

Komentar (1)

Aku pikir tidak ada yang menjawab ini belum lol! Tapi, hei, di sini's saya sendiri pergi di itu:

import random

def random_alphanumeric(limit):
    #ascii alphabet of all alphanumerals
    r = (range(48, 58) + range(65, 91) + range(97, 123))
    random.shuffle(r)
    return reduce(lambda i, s: i + chr(s), r[:random.randint(0, len(r))], "")
Komentar (2)

Jika anda membutuhkan sebuah string acak daripada pseudo random satu, anda harus menggunakan os.urandom sebagai sumber

from os import urandom
from itertools import islice, imap, repeat
import string

def rand_string(length=5):
    chars = set(string.ascii_uppercase + string.digits)
    char_gen = (c for c in imap(urandom, repeat(1)) if c in chars)
    return ''.join(islice(char_gen, None, length))
Komentar (5)

Metode ini sedikit lebih cepat, dan sedikit lebih menjengkelkan, dari acak.pilihan() metode Ignacio diposting.

Ia mengambil keuntungan dari sifat pseudo-random algoritma, dan bank-bank di bitwise dan dan pergeseran yang cepat dari yang menghasilkan nomor acak baru untuk masing-masing karakter.

# must be length 32 -- 5 bits -- the question didn't specify using the full set
# of uppercase letters ;)
_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'

def generate_with_randbits(size=32):
    def chop(x):
        while x:
            yield x & 31
            x = x >> 5
    return  ''.join(_ALPHABET[x] for x in chop(random.getrandbits(size * 5))).ljust(size, 'A')

...membuat generator yang mengeluarkan 5 bit angka-angka pada suatu waktu 0..31 sampai tidak ada yang tersisa

...join() hasil dari generator nomor acak dengan tepat bit

Dengan Waktuhal, untuk 32-karakter string, waktu itu:

[('generate_with_random_choice', 28.92901611328125),
 ('generate_with_randbits', 20.0293550491333)]

...tapi untuk 64 karakter string, randbits kehilangan keluar ;)

Saya mungkin akan tidak pernah menggunakan pendekatan ini dalam kode produksi kecuali aku benar-benar tidak menyukai rekan kerja saya.

edit: diperbarui sesuai dengan pertanyaan (huruf besar dan angka saja), dan menggunakan operator bitwise & dan >> bukan % dan //

Komentar (0)

I'd lakukan cara ini:

import random
from string import digits, ascii_uppercase

legals = digits + ascii_uppercase

def rand_string(length, char_set=legals):

    output = ''
    for _ in range(length): output += random.choice(char_set)
    return output

Atau hanya:

def rand_string(length, char_set=legals):

    return ''.join( random.choice(char_set) for _ in range(length) )
Komentar (0)

Menggunakan Numpy's acak.pilihan() fungsi

import numpy as np
import string        

if __name__ == '__main__':
    length = 16
    a = np.random.choice(list(string.ascii_uppercase + string.digits), length)                
    print(''.join(a))

Dokumentasi di sini http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html

Komentar (2)
>>> import string 
>>> import random

berikut logika masih menghasilkan 6 karakter sampel acak

>>> print ''.join(random.sample((string.ascii_uppercase+string.digits),6))
JT7K3Q

Tidak perlu kalikan dengan 6

>>> print ''.join(random.sample((string.ascii_uppercase+string.digits)*6,6))

TK82HK
Komentar (1)

Kadang-kadang 0 (nol) & O (huruf O) dapat membingungkan. Jadi saya gunakan

import uuid
uuid.uuid4().hex[:6].upper().replace('0','X').replace('O','Y')
Komentar (0)

Bagi anda yang menikmati fungsional python:

from itertools import imap, starmap, islice, repeat
from functools import partial
from string import letters, digits, join
from random import choice

join_chars = partial(join, sep='')
identity = lambda o: o

def irand_seqs(symbols=join_chars((letters, digits)), length=6, join=join_chars, select=choice, breakup=islice):
    """ Generates an indefinite sequence of joined random symbols each of a specific length
    :param symbols: symbols to select,
        [defaults to string.letters + string.digits, digits 0 - 9, lower and upper case English letters.]
    :param length: the length of each sequence,
        [defaults to 6]
    :param join: method used to join selected symbol, 
        [defaults to ''.join generating a string.]
    :param select: method used to select a random element from the giving population. 
        [defaults to random.choice, which selects a single element randomly]
    :return: indefinite iterator generating random sequences of giving [:param length]
    >>> from tools import irand_seqs
    >>> strings = irand_seqs()
    >>> a = next(strings)
    >>> assert isinstance(a, (str, unicode))
    >>> assert len(a) == 6
    >>> assert next(strings) != next(strings)
    """
    return imap(join, starmap(breakup, repeat((imap(select, repeat(symbols)), None, length))))

Ini menghasilkan waktu yang tidak terbatas [tak terbatas] iterator, bergabung dengan urutan acak, dengan terlebih dahulu menghasilkan waktu yang tidak terbatas urutan yang dipilih secara acak simbol dari pemberian renang, kemudian melanggar urutan ini suhu udara turun menjadi bagian-bagian yang kemudian bergabung, itu harus bekerja dengan urutan yang mendukung getitem, secara default hanya menghasilkan urutan acak dari alpha numerik huruf, meskipun anda dapat dengan mudah memodifikasi untuk menghasilkan hal-hal lain:

misalnya untuk menghasilkan random tupel digit:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> next(irand_tuples)
(0, 5, 5, 7, 2, 8)
>>> next(irand_tuples)
(3, 2, 2, 0, 3, 1)

jika anda don't ingin anda gunakan berikutnya untuk generasi anda hanya dapat membuatnya callable:

>>> irand_tuples = irand_seqs(xrange(10), join=tuple)
>>> make_rand_tuples = partial(next, irand_tuples) 
>>> make_rand_tuples()
(1, 6, 2, 8, 1, 9)

jika anda ingin menghasilkan urutan on the fly hanya mengatur bergabung dengan identitas.

>>> irand_tuples = irand_seqs(xrange(10), join=identity)
>>> selections = next(irand_tuples)
>>> next(selections)
8
>>> list(selections)
[6, 3, 8, 2, 2]

Seperti orang lain telah disebutkan jika anda membutuhkan keamanan yang lebih kemudian menetapkan sesuai pilih fungsi:

>>> from random import SystemRandom
>>> rand_strs = irand_seqs(select=SystemRandom().choice)
'QsaDxQ'

default pemilih adalah pilihan yang mungkin pilih simbol yang sama beberapa kali untuk masing-masing potongan, jika bukan anda'd mau sama anggota yang dipilih paling banyak sekali untuk setiap chunk kemudian, salah satu kemungkinan penggunaan:

>>> from random import sample
>>> irand_samples = irand_seqs(xrange(10), length=1, join=next, select=lambda pool: sample(pool, 6))
>>> next(irand_samples)
[0, 9, 2, 3, 1, 6]

kita menggunakan sampel sebagai pemilih, untuk melakukan pilihan lengkap, sehingga potongan yang benar-benar panjang 1, dan untuk bergabung dengan kami hanya dengan panggilan next yang menjemput berikutnya benar-benar dihasilkan chunk, diberikan contoh ini tampaknya sedikit rumit dan itu adalah ...

Komentar (0)

(1) Ini akan memberikan anda semua huruf dan angka:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_uppercase))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey 

(2) Jika anda kemudian ingin memasukkan huruf pada kunci anda, maka ini juga akan bekerja:

import string, random
passkey=''
for x in range(8):
    if random.choice([1,2]) == 1:
        passkey += passkey.join(random.choice(string.ascii_letters))
    else:
        passkey += passkey.join(random.choice(string.digits))
print passkey  
Komentar (0)

ini adalah mengambil Anurag Uniyal 's respon dan sesuatu yang saya telah bekerja pada diri saya sendiri.


import random
import string

oneFile = open('‪Numbers.txt', 'w')
userInput = 0
key_count = 0
value_count = 0
chars = string.ascii_uppercase + string.digits + string.punctuation

for userInput in range(int(input('How many 12 digit keys do you want?'))):
    while key_count 
Komentar (0)
import random
q=2
o=1
list  =[r'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','s','0','1','2','3','4','5','6','7','8','9','0']
while(q>o):
    print("")

    for i in range(1,128):
        x=random.choice(list)
        print(x,end="")

Di sini panjang dari string yang dapat berubah dalam lingkaran saya.e for i in range(1,panjang) Ini adalah algoritma sederhana yang mudah dipahami. menggunakan daftar sehingga anda dapat membuang karakter yang anda tidak perlu.

Komentar (0)
>>> import random
>>> str = []
>>> chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
>>> num = int(raw_input('How long do you want the string to be?  '))
How long do you want the string to be?  10
>>> for k in range(1, num+1):
...    str.append(random.choice(chars))
...
>>> str = "".join(str)
>>> str
'tm2JUQ04CK'

Yang acak.pilihan fungsi mengambil sebuah entri acak dalam daftar. Anda juga dapat membuat sebuah daftar sehingga anda dapat menambahkan karakter dalam untuk pernyataan. Pada akhir str ['t', 'm', '2', 'J', 'U', 'Q', '0', '4', 'C', 'K'], tapi str = "".bergabung(str) mengurus itu, meninggalkan anda dengan 'tm2JUQ04CK'.

Harap ini membantu!

Komentar (1)