对于一个项目,我需要一种创建数千个随机字符串的方法,同时保持冲突率低。我要求这些随机字符串只有12个字符长,且全部为大写字母。有什么建议吗?
代码:
from random import choice
from string import ascii_uppercase
print(''.join(choice(ascii_uppercase) for i in range(12)))
输出:
5个示例:
QPUPZVVHUNSN
EFJACZEBYQEB
QBQJJEEOYTZY
EOJUSUEAJEEK
QWRWLIWDTDBD
编辑:
如果您仅需要数字,请使用digits
常量,而不是来自string
模块的ascii_uppercase
。
3个例子:
229945986931
867348810313
618228923380
import digits
print(''.join(choice(ascii_uppercase + digits) for i in range(12)))
- Sandeep Kanabarstring.digits
在 Python 3 中一直存在,从 3.0 版本开始。 - TheDiveO使用 Django
,您可以在 django.utils.crypto
模块中使用 get_random_string
函数。
get_random_string(length=12,
allowed_chars=u'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
Returns a securely generated random string.
The default length of 12 with the a-z, A-Z, 0-9 character set returns
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
示例:
get_random_string()
u'ngccjtxvvmr9'
get_random_string(4, allowed_chars='bqDE56')
u'DDD6'
但如果您不想使用 Django
,这里 有其独立的代码:
代码:
import random
import hashlib
import time
SECRET_KEY = 'PUT A RANDOM KEY WITH 50 CHARACTERS LENGTH HERE !!'
try:
random = random.SystemRandom()
using_sysrandom = True
except NotImplementedError:
import warnings
warnings.warn('A secure pseudo-random number generator is not available '
'on your system. Falling back to Mersenne Twister.')
using_sysrandom = False
def get_random_string(length=12,
allowed_chars='abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
"""
Returns a securely generated random string.
The default length of 12 with the a-z, A-Z, 0-9 character set returns
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
"""
if not using_sysrandom:
# This is ugly, and a hack, but it makes things better than
# the alternative of predictability. This re-seeds the PRNG
# using a value that is hard for an attacker to predict, every
# time a random string is required. This may change the
# properties of the chosen random sequence slightly, but this
# is better than absolute predictability.
random.seed(
hashlib.sha256(
("%s%s%s" % (
random.getstate(),
time.time(),
SECRET_KEY)).encode('utf-8')
).digest())
return ''.join(random.choice(allowed_chars) for i in range(length))
可以制作一个生成器:
from string import ascii_uppercase
import random
from itertools import islice
def random_chars(size, chars=ascii_uppercase):
selection = iter(lambda: random.choice(chars), object())
while True:
yield ''.join(islice(selection, size))
random_gen = random_chars(12)
print next(random_gen)
# LEQIITOSJZOQ
print next(random_gen)
# PXUYJTOTHWPJ
当需要时,只需从生成器中提取即可... 可以使用 next(random_gen)
在需要它们时进行提取,或者例如使用 random_200 = list(islice(random_gen, 200))
...
functools.partial
可以做到这一点。如果内部循环中没有Python级别的生成器和几个Python级别的函数调用,那么list
和islice
在C中的事实将是一个优势。泄漏循环变量很烦人,但没有理由避免使用列表推导式。 - user2357112next(random_chars(n))
,而对于普通函数则只需使用 random_chars(n)
。循环遍历 k 个随机字符串的方式为 for s in islice(random_chars(n), k):
,而对于普通函数则是 for i in xrange(k): s = random_chars(n)
。我认为 islice
和 next
调用是警告信号,表明您实际上并不想在这里使用生成器。 - user2357112#!/bin/python3
import random
import string
def f(n: int) -> str:
bytes(random.choices(string.ascii_uppercase.encode('ascii'),k=n)).decode('ascii')
针对非常大的n,运行速度更快。避免字符串连接。
该函数生成指定长度的大写字母随机字符串。
例如:长度为6,将生成以下随机序列模式
YLNYVQ
import random as r
def generate_random_string(length):
random_string = ''
random_str_seq = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in range(0,length):
if i % length == 0 and i != 0:
random_string += '-'
random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
return random_string
random_str_seq = "ABC@#$%^!&_+|*()OPQRSTUVWXYZ"
可以得到更加复杂的结果。 - Iqra.set
存储已生成的值,实现一个不重复的随机生成器函数。请注意,在处理非常大的字符串或数量时,这将会占用一些内存,并且可能会稍微减慢速度。当达到给定数量或最大可能组合时,generator
将停止运行。#!/usr/bin/env python
from typing import Generator
from random import SystemRandom as RND
from string import ascii_uppercase, digits
def string_generator(size: int = 1, amount: int = 1) -> Generator[str, None, None]:
"""
Return x random strings of a fixed length.
:param size: string length, defaults to 1
:type size: int, optional
:param amount: amount of random strings to generate, defaults to 1
:type amount: int, optional
:yield: Yield composed random string if unique
:rtype: Generator[str, None, None]
"""
CHARS = list(ascii_uppercase + digits)
LIMIT = len(CHARS) ** size
count, check, string = 0, set(), ''
while LIMIT > count < amount:
string = ''.join(RND().choices(CHARS, k=size))
if string not in check:
check.add(string)
yield string
count += 1
for my_count, my_string in enumerate(string_generator(12, 20)):
print(my_count, my_string)
输出:
0 IESUASWBRHPD
1 JGGO1THKLC9K
2 BW04A5GWBA7K
3 KDQTY72BV1S9
4 FAOL5L28VVMN
5 NLDNNBGHTRTI
6 2RV6TE6BCQ8K
7 B79B8FBPUD07
8 89VXXRHPUN41
9 DFC8QJUY6HRB
10 FXYYDKVQHC5Z
11 57KTZE67RSCU
12 389H1UT7N6CI
13 AKZMN9XITAVB
14 6T9ACH3GDAYG
15 CH8RJUQMTMBE
16 SPQ7E02ZLFD3
17 YD6JFXGIF3YF
18 ZUSA2X6OVNCN
19 JQRH6LR229Y4