Pertanyaan Pembuatan string acak dengan huruf besar dan digit dalam Python


Saya ingin menghasilkan string ukuran N.

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

  • 6U1S75
  • 4Z4UKK
  • U911K4

Bagaimana saya bisa mencapai ini dalam pythonic cara?


997
2018-02-13 12:23


asal


Jawaban:


Jawab dalam satu baris:

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

atau bahkan mulai lebih pendek dengan menggunakan Python 3.6 random.choices():

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

Versi yang lebih aman secara kriptografi; Lihat https://stackoverflow.com/a/23728630/2213647:

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

Secara detail, dengan fungsi bersih untuk digunakan kembali lebih lanjut:

>>> 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 ?

Kami mengimpor string, modul yang berisi urutan karakter ASCII umum, dan random, modul yang berhubungan dengan generasi acak.

string.ascii_uppercase + string.digits hanya menggabungkan daftar karakter yang mewakili karakter ASCII dan digit teratas:

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

Kemudian kami menggunakan pemahaman daftar untuk membuat daftar elemen 'n':

>>> 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']

Pada contoh di atas, kami menggunakan [ untuk membuat daftar, tetapi kami tidak di id_generator berfungsi sehingga Python tidak membuat daftar dalam memori, tetapi menghasilkan elemen dengan cepat, satu per satu (lebih lanjut tentang ini sini).

Alih-alih meminta untuk menciptakan 'n' kali string elem, kami akan meminta Python untuk membuat 'n' kali karakter acak, dipilih dari urutan karakter:

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

Karena itu random.choice(chars) for _ in range(size) benar-benar membuat urutan size karakter. Karakter yang dipilih secara acak chars:

>>> [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']

Lalu kita hanya bergabung dengan mereka dengan string kosong sehingga urutannya menjadi 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'

2049
2018-02-13 12:26



Kueri Stack Overflow ini adalah hasil Google teratas saat ini untuk "string acak Python". Jawaban teratas saat ini adalah:

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

Ini adalah metode yang bagus, tetapi PRNG secara acak tidak aman secara kriptografi. Saya berasumsi banyak orang yang meneliti pertanyaan ini akan ingin menghasilkan string acak untuk enkripsi atau kata sandi. Anda dapat melakukannya dengan aman dengan membuat perubahan kecil pada kode di atas:

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

Menggunakan random.SystemRandom() bukan hanya menggunakan acak / dev / urandom pada * mesin nix dan CryptGenRandom() di Windows. Ini adalah PRNG yang aman secara kriptografi. Menggunakan random.choice dari pada random.SystemRandom().choice dalam sebuah aplikasi yang membutuhkan PRNG yang aman dapat berpotensi menghancurkan, dan mengingat popularitas pertanyaan ini, saya yakin kesalahan itu telah dilakukan berkali-kali.

Jika Anda menggunakan python3.6 atau lebih baru, Anda dapat menggunakan yang baru rahasia modul.

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

Dokumen modul juga membahas cara-cara mudah menghasilkan token aman dan praktik terbaik.


448
2018-05-19 01:41



Cukup gunakan Python builtin uuid:

Jika UUID baik-baik saja untuk tujuan Anda, gunakan built-in uuid paket.

Solusi Satu Jalur:

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

Dalam Versi Kedalaman:

Contoh:

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

Jika Anda benar-benar membutuhkan format Anda (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

132
2018-06-26 15:11



Cara yang lebih sederhana, lebih cepat tetapi sedikit kurang acak adalah dengan menggunakannya random.sample daripada memilih setiap huruf secara terpisah, Jika n-repetisi dibolehkan, perbesar basis acak Anda sebanyak n kali misalnya

import random
import string

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

catatan: random.sample mencegah penggunaan kembali karakter, mengalikan ukuran set karakter membuat beberapa repetisi mungkin, tetapi mereka masih kurang mungkin maka mereka dalam pilihan acak murni. Jika kita pergi untuk string panjang 6, dan kita memilih 'X' sebagai karakter pertama, dalam contoh pilihan, peluang mendapatkan 'X' untuk karakter kedua sama dengan kemungkinan mendapatkan 'X' sebagai karakter pertama. Dalam implementasi random.sample, peluang mendapatkan 'X' karena karakter berikutnya hanya 6/7 kemungkinan untuk mendapatkannya sebagai karakter pertama


41
2018-02-13 12:44



import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str adalah nilai acak seperti 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str aku s 'CEA8B32E00934AAEA8C005A35D85A5C0'


22
2017-12-01 10:04



Mengambil jawaban dari Ignacio, ini bekerja dengan Python 2.6:

import random
import string

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

Contoh keluaran:

JQUBT2


18
2018-02-13 12:35



Cara yang lebih cepat, mudah dan lebih fleksibel untuk melakukan ini adalah dengan menggunakan strgen modul (pip install StringGenerator).

Hasilkan string acak 6-karakter dengan huruf besar dan angka di atas:

>>> 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']

Menjamin satu karakter "khusus" dalam string:

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

Warna HTML acak:

>>> 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 waktu pengembangan daripada solusi di atas. Solusi dari Ignacio adalah menjalankan waktu berjalan tercepat dan merupakan jawaban yang benar menggunakan Pustaka Standar Python. Tetapi Anda hampir tidak akan pernah menggunakannya dalam bentuk itu. Anda akan ingin menggunakan SystemRandom (atau fallback jika tidak tersedia), pastikan set karakter yang diperlukan diwakili, gunakan unicode (atau tidak), pastikan invoice berturut menghasilkan string unik, gunakan subset dari salah satu kelas karakter modul string, dll. Ini semua membutuhkan lebih banyak kode daripada di jawaban yang diberikan. Berbagai upaya untuk menggeneralisasi solusi semua memiliki keterbatasan yang strgen memecahkan dengan keringkasan yang lebih besar dan kekuatan ekspresif menggunakan bahasa template sederhana.

Ada di PyPI:

pip install StringGenerator

Pengungkapan: Saya adalah pengarang modul strgen.


16
2017-08-26 11:47



Jika Anda membutuhkan string acak daripada acak pseudo satu, Anda harus menggunakan os.urandom sebagai sumbernya

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))

8
2017-09-13 04:32