大文字と数字を使用したランダムな文字列の生成


1336

サイズNの文字列を生成したい。

数字と次のような大文字の英字で構成する必要があります。

  • 6U1S75
  • 4Z4UKK
  • U911K4

どうすればこれをpythonicの方法で実現できますか?


11
これは非常に人気のある質問です。私はトップ3の回答は、文字列の大きさの範囲のための衝突確率をIE用の専門家は、これらの乱数の一意の彼のテイクを追加し、6から16に言うたい
ユーザー

8
@buffer可能な組み合わせの数を計算するのは簡単です。10個の数字+ 26文字= 36個の可能な文字、6の累乗(文字列の長さ)は約20億に相当します。ランダムな値の私の経験則は、「地球上のすべての人間の値を生成した場合、それぞれにいくつの値があるか」です。この場合、1人あたりの値は1つ未満になるため、これがユーザーまたはオブジェクトの識別である場合は、文字が少なすぎます。1つの代替方法は、小文字を追加することです。これにより、62 ^ 6 = 570億近くの一意の値になります。
Blixt

1
そして、世界の人口について考えるのはばかげているように見えるかもしれませんが、それは単に衝突の可能性のために巨大なバッファーが必要だからです。誕生日の問題を参照してください:en.wikipedia.org/wiki/Birthday_problem
Blixt

1
@buffer、この答えに興味があるでしょう。
Anish Ramaswamy、

これは「暗号的に安全なランダム文字列の生成...」に名前を変更すべきではありませんか?
smci 2018

回答:


2541

1行で回答します。

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

または、Python 3.6以降ではさらに短いrandom.choices()

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

暗号化により安全なバージョン。https://stackoverflow.com/a/23728630/2213647を参照してください

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

詳細には、さらに再利用するためのクリーン関数を使用します。

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

それはどのように機能しますか?

string一般的なASCII文字のシーケンスを含むモジュールであるをインポートし、randomランダム生成を処理するモジュール。

string.ascii_uppercase + string.digits 大文字のASCII文字と数字を表す文字のリストを連結するだけです。

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

次に、リスト内包表記を使用して「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']

上記の例では[、リストを作成するために使用しますが、id_generator関数内にはないため、Pythonはメモリ内にリストを作成しませんが、要素を1つずつオンザフライで生成します(詳細はこちら))。

文字列の 'n'回の作成を要求する代わりにelem、一連の文字から選択されたランダムな文字の 'n'回の作成をPythonに要求します。

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

したがって、random.choice(chars) for _ in range(size)実際にはsize文字のシーケンスを作成しています。からランダムに選ばれたキャラクター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']

次に、それらを空の文字列で結合して、シーケンスが文字列になるようにします。

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

7
@jorelli:リストの内包ではありません。それはジェネレータ式です。
Ignacio Vazquez-Abrams

2
@joreilli:回答にこれに関する簡単なメモを追加し、反復可能、リスト内包表記、ジェネレーター、そして最終的にyieldキーワードに関する詳細な回答へのリンクを追加しました。
e-satis

1
私は置き換えたいrangexrange
Jan-Philip Gehrcke博士、2013

1
非常に便利。興味深いことに、DjangoはパスワードとCSRFトークンを生成するためにこのコードを使用しています。あなたは交換する必要がありますがrandomrandom.SystemRandom()github.com/django/django/blob/...
ユーザー

1
@ Chiel92は、random.sample置換せずに、つまり、OPの要件にない文字を繰り返す可能性なしにサンプルを作成します。ほとんどのアプリケーションでそれが望ましいとは思いません。
オントロジスト

557

このスタックオーバーフローの質問は、「ランダム文字列Python」の現在の上位のGoogle結果です。現在のトップの答えは:

''.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()だけではなく、ランダムな用途のは/ dev / urandomが* nixのマシン上とCryptGenRandom()Windowsで。これらは暗号的に安全なPRNGです。のrandom.choice代わりに使用random.SystemRandom().choice安全なPRNGを必要とするアプリケーションの、壊滅的になる可能性があり、この質問の人気を考えると、間違いはすでに何度も犯されていると思います。

python3.6以降を使用している場合は、MSeifertの回答に記載されているように、新しいシークレットモジュールを使用できます。

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

モジュールのドキュメントでは、安全なトークン生成する便利な方法とベストプラクティスについても説明しています。


3
はい、の公式標準ライブラリrandomはこれを警告しています: " 警告:このモジュールの疑似乱数生成器はセキュリティ目的で使用すべきではありません。暗号的に安全な疑似乱数生成器が必要な場合はos.urandom()またはSystemRandomを使用してください。 」これが参照です: random.SystemRandomおよびos.urandom
lord63。j

4
すばらしい答えです。小さな注意:string.uppercaseロケールセットによっては予期しない結果が生じる可能性があるように変更しました。使用するstring.ascii_uppercase(またはstring.ascii_letters + string.digits代わりbase36のbase62ため)は符号化が関与している場合には安全です。
Blixt

小さなメモ- 後者はメモリ内リストを生成するので、前者は反復子を作成するので、xrange代わりに使用する方が良いrangeです。
Guyarad

2
ランダムな文字列は常に一意になりますか?主キーを使用したかった。
shakthydoss 2016

3
@shakthydoss:いいえ。ランダムな文字列である「AAA000」を返し、次にランダムな文字列である「AAA000」を返す場合があります。一意性のチェックを明示的に追加する必要があります。
usr2564301 2018年

189

Pythonの組み込みuuidを使用するだけです。

UUIDが目的に合っている場合は、組み込みのuuidパッケージを使用します。

1行のソリューション:

import uuid; uuid.uuid4().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

14
+1質問の背景を考えるため。おそらく、uuid1とuuid4の違いを簡単に説明できます。
Thomas Ahle 14年

1
3回続けてuuid1を実行すると、d161fd16-ab0f-11e3-9314-00259073e4a8、d3535b56-ab0f-11e3-9314-00259073e4a8、d413be32-ab0f-11e3-9314-00259073e4a8が得られ、これらはすべて疑わしいと思われます(最初の8文字は異なり、残りは同じです)。これはuuid4には当てはまりません
チェイス・ロバーツ

9
uui1:ホストID、シーケンス番号、および現在の時刻からUUIDを生成します。uuid4:ランダムなUUIDを生成します。
Bijan

7
文字列のキャストとハイフンの置換をスキップする場合は、my_uuid.get_hex()またはuuid.uuid4()。get_hex()を呼び出すだけで、ハイフンのないuuidから生成された文字列が返されます。
dshap 2014

8
UUIDを切り捨てることは良い考えですか?どれだけ小さいかに応じてstring_length、衝突の確率が問題になる可能性があります。
ユーザー

44

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」を選択すると、選択例では、2番目の文字の「X」を取得するオッズは、「X」を取得するオッズと同じです。最初の文字。random.sample実装では、後続の文字として「X」を取得する確率は、最初の文字として取得する可能性が6/7だけです


8
この方法は悪くありませsampleんが、同じ文字が2回リストされることはないので、各文字を個別に選択するほどランダムではありません。もちろん、それN以上では失敗します36
ボビンス、2013

与えられたユースケース(繰り返しがない場合)でも、それが依然として最良の解決策であると言います。
Anurag Uniyal 2010

3
例の1つにリピートがあるので、彼がリピートを禁止しようとしているのではないかと思います。
Mark Byers

5
random.sampleが文字の再利用を防ぐ場合、文字セットのサイズを増やすことで複数の繰り返しが可能になりますが、それらは純粋にランダムに選択される可能性は低くなります。長さ6の文字列の場合、最初の文字として「X」を選択すると、選択例では、2番目の文字の「X」を取得するオッズは、「X」を取得するオッズと同じです。最初の文字。random.sample実装では、後続の文字として「X」を取得する確率は、最初の文字として取得する可能性の5/6です。
ピカリー2013

1
生成された文字列を移動すると、特定の文字が繰り返される可能性が低下します。26文字の大文字と10桁の数字から6文字の文字列を生成し、各文字を個別にランダムに選択すると、特定の文字列が1 /(36 ^ 6)の頻度で発生します。「FU3WYE」と「XXXXXX」が生成される可能性は同じです。サンプル実装では、「XXXXXX」を生成する可能性は(1 /(36 ^ 6))*((6/6)*(5/6)*(4/6)*(3/6)*(2 / 6)*(1/6))は、random.sampleの非置換機能によるものです。「XXXXXX」はサンプル実装では324倍少ない可能性があります。
ピカリー2013

32
import uuid
lowercase_str = uuid.uuid4().hex  

lowercase_str のようなランダムな値です 'cea8b32e00934aaea8c005a35d85a5c0'

uppercase_str = lowercase_str.upper()

uppercase_str です 'CEA8B32E00934AAEA8C005A35D85A5C0'


2
uppercase_str[:N+1]
Yajo

@Yajoええ、スライスを使用して制限できます
Savad KP

2
@八条:いいえ、16進数の値をスライスする必要はありません。大文字と数字の完全なシーケンスと比較して、エントロピーを削除します。おそらく、代わりに値をbase32エンコードします(エントロピーをわずかに減らし、36 ** nから32 ** nに、さらに16 ** nよりも優れています)。
Martijn Pieters

19

これをより速く、より簡単に、より柔軟に行う方法は、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']

文字列内の1つの「特殊」文字を保証します。

>>> 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を使用(または使用しない)し、連続した呼び出しで一意の文字列が生成されることを確認し、文字列モジュール文字クラスの1つのサブセットを使用します。 etc.これはすべて、提供された回答よりも多くのコードを必要とします。ソリューションを一般化しようとするさまざまな試みはすべて、単純なテンプレート言語を使用してstrgenがより簡潔かつ表現力をもって解決する制限があります。

PyPIにあります:

pip install StringGenerator

開示:私はstrgenモジュールの作成者です。


12

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

もう1つの注意:リスト内包表記はstr.join、ジェネレータ式を使用する場合よりも高速です。


10

別のスタックオーバーフローの回答に基づく、ランダムな文字列とランダムな16進数を作成する最も軽量な方法は、承認された回答よりも優れたバージョンです。

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

はるかに高速。


1
「AF」のみを使用し、「A-Z」は使用しませんが、これは素晴らしいです。また、parameterrizeを実行すると、コードの見栄えが少し悪くなりNます。
Thomas Ahle 14年

9

疑似ランダム文字列ではなくランダム文字列が必要な場合は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))

3
os.urandom疑似ランダムではないのですか?よりランダムな数値を生成するためにより良いアルゴリズムを使用しているかもしれませんが、それでも疑似ランダムです。
Tyilo

@Tyilo、との違いを知っ/dev/randomてい/dev/urandomます。問題は、その/dev/random有用性を制限する十分なエントロピーがない場合にブロックすることです。以下のためにワンタイムパッド /dev/urandomは良い十分ではありませんが、私はそれがより良いここで擬似ランダムよりだと思います。
John La Rooy

1
私は両方のことを言う/dev/randomとは/dev/urandom、擬似ランダムであるが、それはあなたの定義に依存する場合があります。
Tyilo

9

まだ誰もこれに答えていなかったと思いました笑 しかし、ねえ、ここに私自身の挑戦があります:

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

4
私はこれに反対票を投じませんが、それはそのような単純な仕事にはあまりにも複雑すぎると思います。戻り式はモンスターです。シンプルは複雑よりも優れています。
カールスミス

12
@CarlSmith、本当の私の解決策はタスクに対して少しやり過ぎに思えますが、他のより簡単な解決策を知っていて、良い答えへの別のルートを見つけたかっただけです。自由がなければ創造性が危ぶまれるので投稿しました。
nemesisfixx

7

このメソッドは、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')

...一度に5ビットの数値を取り出し、0から31まで、何もなくなるまで生成する

... join()正しいビットの乱数に対するジェネレータの結果

Timeitでは、32文字の文字列の場合、タイミングは次のとおりでした。

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

...しかし64文字の文字列の場合、randbitsは負けます;)

同僚が本当に嫌いでない限り、私はおそらくこの方法を実稼働コードで使用しないでしょう。

編集:質問に合わせて更新され(大文字と数字のみ)、%と//の代わりにビットごとの演算子&と>>を使用します


5

私はこのようにします:

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

5

Numpyのrandom.choice()関数を使用する

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

ドキュメントはこちらhttp://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.random.choice.html


1
python stdlib randomの代わりにnumpy randomを使用する必要があるのはなぜですか?
Pax0r

長さ、可変確率、置換による選択などの引数により多くのオプションを許可するためです。
Mudit Jain

5

0(ゼロ)とO(文字O)は混乱することがあります。だから私は

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

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

3
ただし、このバリアントでは、すべてのキャラクターが強制的に異なります。また、Nがlen(string.ascii_uppercase + string.digits)より大きい場合は機能しません
MarSoft

3

機能的な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))))

最初に与えられたプールからランダムに選択されたシンボルの不定シーケンスを生成し、次にこのシーケンスを長さの部分に分割してから結合することにより、結合されたランダムシーケンスの不定[無限]イテレータを生成します。 、デフォルトでは単に英数字のランダムなシーケンスを生成しますが、簡単に変更して他のものを生成することもできます。

たとえば、数字のランダムなタプルを生成するには:

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

nextを世代に使用したくない場合は、単純に呼び出し可能にすることができます。

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

オンザフライでシーケンスを生成する場合は、単純にjoinをidentityに設定します。

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

より多くのセキュリティが必要な場合は他の人が述べたように、適切な選択機能を設定します:

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

デフォルトのセレクターはchoice、チャンクごとに同じシンボルを複数回選択する可能性があります。代わりに、チャンクごとに同じメンバーを最大1回選択する場合は、1つの可能な使用法です。

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

sampleセレクターとして使用して完全な選択を行うため、チャンクは実際には長さ1であり、結合するにはnext、次の完全に生成されたチャンクをフェッチする呼び出しを実行します。


3

(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  

3

これは、Anurag Uniyalの反応と私が自分で取り組んでいたことの一部です。

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

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

お役に立てれば!


いいですがrange(num)、代わりに使用でき、strは文字列str += random.choice(chars)でした。
sashk

2
import string
from random import *
characters = string.ascii_letters + string.punctuation  + string.digits
password =  "".join(choice(characters) for x in range(randint(8, 16)))
print password

2
このコードは質問に答えることがありますが、なぜまたはどのように質問に答えるについて追加のコンテキストを提供すると、長期的な価値が大幅に向上します。回答を編集して、説明を追加してください。
Toby Speight 2016年

2
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="")

ここで、文字列の長さはforループで変更できます。つまり、for i(range(1、length)内)は、理解しやすいシンプルなアルゴリズムです。リストを使用するので、不要な文字を破棄できます。


1

簡単なもの:

import string
import random
character = string.lowercase + string.uppercase + string.digits + string.punctuation
char_len = len(character)
# you can specify your password length here
pass_len = random.randint(10,20)
password = ''
for x in range(pass_len):
    password = password + character[random.randint(0,char_len-1)]
print password

0

私はあなたに次のオプションを提案したいと思います:

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]

0

2つの方法:

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

最初の方法のパフォーマンスが優れています。


0

私はほとんどすべての答えを調べましたが、どれも簡単に見えません。ランダムなパスワードの作成に一般的に使用されるpassgenライブラリを試すことをお勧めします。

長さ、句読点、数字、文字、大文字小文字を選択して、ランダムな文字列を生成できます

ケースのコードは次のとおりです。

from passgen import passgen
string_length = int(input())
random_string = passgen(length=string_length, punctuation=False, digits=True, letters=True, case='upper')

0

文字、数字、「_」、「-」を含むランダムな16バイトIDを生成します

os.urandom(16).translate((f'{string.ascii_letters}{string.digits}-_'*4).encode('ascii'))


0

私はさまざまな答えを見ていて、秘密の文書を読むのに時間をかけました

シークレットモジュールは、パスワード、アカウント認証、セキュリティトークン、関連するシークレットなどのデータを管理するのに適した、暗号学的に強力な乱数を生成するために使用されます。

特に、シークレットは、セキュリティや暗号化ではなく、モデリングとシミュレーション用に設計されたランダムモジュールのデフォルトの疑似乱数ジェネレータよりも優先して使用する必要があります。

GoogleドライブIDのようなIDを模倣したい場合、それが何を提供しているかをさらに詳しく調べたところ、非常に便利な機能が見つかりました。

secrets.token_urlsafe([nbytes = None])
nbytesのランダムバイトを含む、ランダムなURLセーフテキスト文字列を返します。テキストはBase64でエンコードされているため、平均して各バイトは約1.3文字になります。nbytesがNoneまたは指定されていない場合、妥当なデフォルトが使用されます。

次のように使用します。

import secrets
import math

def id_generator():
    id = secrets.token_urlsafe(math.floor(32 / 1.3))
    return id

print(id_generator())

32文字の長さのIDを出力します。

joXR8dYbBDAHpVs5ci6iD-oIgPhkeQFk

これはOPの質問とは少し異なることはわかっていますが、私が探していたのと同じユースケースを探していた多くの人にとって、それがまだ役立つと思います。


-1
import string, random
lower = string.ascii_lowercase
upper = string.ascii_uppercase
digits = string.digits
special = '!"£$%^&*.,@#/?'

def rand_pass(l=4, u=4, d=4, s=4):
    p = []
    [p.append(random.choice(lower)) for x in range(l)]
    [p.append(random.choice(upper)) for x in range(u)]
    [p.append(random.choice(digits)) for x in range(d)]
    [p.append(random.choice(special)) for x in range(s)]
    random.shuffle(p)
    return "".join(p)

print(rand_pass())
# @5U,@A4yIZvnp%51

-2

私はこれがよりシンプルでクリーンであることがわかりました。

str_Key           = ""
str_FullKey       = "" 
str_CharacterPool = "01234ABCDEFfghij~>()"
for int_I in range(64): 
    str_Key = random.choice(str_CharacterPool) 
    str_FullKey = str_FullKey + str_Key 

64を変更して長さを変更し、CharacterPoolを変更して、英数字のみ、数字のみ、または奇妙な文字など、必要に応じて変更します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.