number - random.sample python




在Python中隨機生成大寫字母和數字的字符串 (17)

只需使用Python的內置uuid:

如果UUID適合您的用途,請使用內置的uuid軟件包。

一線解決方案:

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

深度版本:

例:

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

如果您確實需要格式(例如,“6U1S75”),則可以這樣做:

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

我想要生成一個大小為N的字符串

它應該由數字和大寫英文字母組成,例如:

  • 6U1S75
  • 4Z4UKK
  • U911K4

我怎樣才能以pythonic方式實現這一點?


(1)這會給你所有的大寫和數字:

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)如果您稍後想要在您的密鑰中包含小寫字母,那麼這也將起作用:

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  

兩種方法:

import random, math

def randStr_1(chars:str, length:int) -> str:
    chars *= math.ceil(length / len(chars))
    chars = letters[0:length]
    chars = list(chars)
    random.shuffle(characters)

    return ''.join(chars)

def randStr_2(chars:str, length:int) -> str:
    return ''.join(random.choice(chars) for i in range(chars))


基準:

from timeit import timeit

setup = """
import os, subprocess, time, string, random, math

def randStr_1(letters:str, length:int) -> str:
    letters *= math.ceil(length / len(letters))
    letters = letters[0:length]
    letters = list(letters)
    random.shuffle(letters)
    return ''.join(letters)

def randStr_2(letters:str, length:int) -> str:
    return ''.join(random.choice(letters) for i in range(length))
"""

print('Method 1 vs Method 2', ', run 10 times each.')

for length in [100,1000,10000,50000,100000,500000,1000000]:
    print(length, 'characters:')

    eff1 = timeit("randStr_1(string.ascii_letters, {})".format(length), setup=setup, number=10)
    eff2 = timeit("randStr_2(string.ascii_letters, {})".format(length), setup=setup, number=10)
    print('\t{}s : {}s'.format(round(eff1, 6), round(eff2, 6)))
    print('\tratio = {} : {}\n'.format(eff1/eff1, round(eff2/eff1, 2)))

輸出:

Method 1 vs Method 2 , run 10 times each.

100 characters:
    0.001411s : 0.00179s
    ratio = 1.0 : 1.27

1000 characters:
    0.013857s : 0.017603s
    ratio = 1.0 : 1.27

10000 characters:
    0.13426s : 0.151169s
    ratio = 1.0 : 1.13

50000 characters:
    0.709403s : 0.855136s
    ratio = 1.0 : 1.21

100000 characters:
    1.360735s : 1.674584s
    ratio = 1.0 : 1.23

500000 characters:
    6.754923s : 7.160508s
    ratio = 1.0 : 1.06

1000000 characters:
    11.232965s : 14.223914s
    ratio = 1.0 : 1.27

第一種方法的性能更好。


一個更簡單,更快,但稍微隨機的方法是使用random.sample而不是分別選擇每個字母,如果允許n次重複,則將隨機基礎擴大n倍,例如

import random
import string

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

注意:random.sample可以防止字符重用,乘以字符集的大小可以實現多次重複,但是它們仍然不太可能,那麼它們是純粹的隨機選擇。 如果我們選擇一個長度為6的字符串,並且我們選擇'X'作為第一個字符,那麼在選擇示例中,獲得'X'的第二個字符的可能性與得到'X'的可能性相同第一個字符。 在random.sample實現中,獲取'X'作為任何後續字符的機率僅為6/7,因此有可能將其作為第一個字符



如果您需要隨機字符串而不是隨機字符串,則應該使用os.urandom作為源

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

從Ignacio得到答案,這適用於Python 2.6:

import random
import string

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

示例輸出:

JQUBT2


從Python 3.6開始,你應該使用secrets模塊, 如果你需要它是加密安全的而不是random模塊的話(否則這個答案與@Ignacio Vazquez-Abrams的相同):

from secrets import choice
import string

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

另外需要注意的一點是:在str.join的情況下,列表理解速度比使用生成器表達式更快!


我想建議你下一個選項:

import crypt
n = 10
crypt.crypt("any sring").replace('/', '').replace('.', '').upper()[-n:-1]

偏執模式:

import uuid
import crypt
n = 10
crypt.crypt(str(uuid.uuid4())).replace('/', '').replace('.', '').upper()[-n:-1]

我會這樣做:

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

要不就:

def rand_string(length, char_set=legals):

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

我還以為沒有人回答這個問題呢! 但是,嘿,這是我自己去做的:

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))], "")

更快,更簡單,更靈活的方法是使用strgen模塊( pip install StringGenerator )。

用大寫字母和數字生成一個6個字符的隨機字符串:

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

獲取一個獨特的列表:

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

確保字符串中包含一個“特殊”字符:

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

隨機的HTML顏色:

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

等等

我們需要意識到這一點:

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

可能沒有數字(或大寫字符)。

strgen開發時間比以上任何解決方案都快。 Ignacio的解決方案是運行時間最快的解決方案,並且是使用Python標準庫的正確答案。 但是你幾乎不會以這種形式使用它。 您將希望使用SystemRandom(或者如果不可用,則使用後備),確保所需的字符集被表示,使用unicode(或不),確保連續的調用產生唯一的字符串,使用字符串模塊字符類之一的子集,等等。這些都需要比提供的答案多得多的代碼。 對解決方案進行概括的各種嘗試都存在限制,strgen通過使用簡單的模板語言來解決更簡潔和表達能力。

它在PyPI上:

pip install StringGenerator

披露:我是strgen模塊的作者。


與Ignacio發布的random.choice()方法相比,此方法稍微快一點,而且更麻煩一些。

它利用了偽隨機算法的性質,並且按位和移位的存儲比為每個字符生成新的隨機數要快。

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

...創建一個發生器,在0..31時刻取出5位數字,直到沒有剩下的數字

...將發生器的結果與正確的位結合起來(隨機數)

有了Timeit,對於32個字符的字符串,時間是:

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

...但是對於64個字符的字符串,randbits丟失;)

除非我真的不喜歡我的同事,否則我絕不會在生產代碼中使用這種方法。

編輯:更新以適應問題(僅限大寫和數字),並使用按位運算符&和>>代替%和//


這個堆棧溢出問題是當前谷歌對“隨機字符串Python”的結果。 當前最重要的答案是:

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

這是一個很好的方法,但隨機PRNG不是加密安全的。 我假設很多研究這個問題的人都希望為加密或密碼生成隨機字符串。 你可以通過在上面的代碼中做一些小改動來安全地做到這一點:

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

使用random.SystemRandom()而不是隨機在* nix機器上使用/ dev / urandom,在Windows中使用CryptGenRandom() 。 這些是密碼安全的PRNG。 在需要安全PRNG的應用程序中使用random.choice而不是random.SystemRandom().choice可能具有潛在的破壞性,並且考慮到此問題的普及,我敢打賭,已經犯了很多錯誤。

如果您使用python3.6或更高版本,則可以使用新的secrets模塊。

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

該模塊文檔還討論了生成安全令牌最佳實踐的便捷方法。


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

random.choice函數在列表中選取一個隨機條目。 您還可以創建一個列表,以便您可以在for語句中附加該字符。 最後str是['t','m','2','J','U','Q','0','4','C','K'],但str = "".join(str)照顧到這一點,給你留下'tm2JUQ04CK'

希望這可以幫助!


>>> import string 
>>> import random

以下邏輯仍然會生成6個字符的隨機樣本

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

不需要乘以6

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

TK82HK

import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str是一個隨機值,如'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str'CEA8B32E00934AAEA8C005A35D85A5C0'







random