Saya ingin menghasilkan sebuah string dari ukuran N.
Ini harus terdiri dari angka dan huruf besar huruf bahasa inggris seperti:
Bagaimana saya bisa mencapai hal ini dalam pythonic cara?
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'
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.
Jika Uuid baik-baik saja untuk keperluan anda, menggunakan built-in uuid paket.
impor uuid; uuid.uuid4().hex.upper()[0:6]
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
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
import uuid
lowercase_str = uuid.uuid4().hex
lowercase_str
adalah nilai acak seperti 'cea8b32e00934aaea8c005a35d85a5c0'
uppercase_str = lowercase_str.upper()
uppercase_str
adalah 'CEA8B32E00934AAEA8C005A35D85A5C0'
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.
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!
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.
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))], "")
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))
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 //
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) )
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
>>> 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
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 ...
(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
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 <= userInput:
key_count += 1
number = random.randint(1, 999)
key = number
text = str(key) + ": " + str(''.join(random.sample(chars*6, 12)))
oneFile.write(text + "\n")
oneFile.close()
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.
>>> 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!