S Ghosh TLDR: Generate Django Secret Key 引用的帖子表明,截至 3.1.3 版本,Django 实际上在后台使用 Python secrets 模块。查看this blob 对应get_random_secret_key 和this other blob 对应get_random_string,我可以看到是这样的:
def get_random_secret_key():
"""
Return a 50 character random string usable as a SECRET_KEY setting value.
"""
chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
return get_random_string(50, chars)
def get_random_string(length, allowed_chars=RANDOM_STRING_CHARS):
"""
Return a securely generated random string.
The bit length of the returned value can be calculated with the formula:
log_2(len(allowed_chars)^length)
For example, with default `allowed_chars` (26+26+10), this gives:
* length: 12, bit length =~ 71 bits
* length: 22, bit length =~ 131 bits
"""
return ''.join(secrets.choice(allowed_chars) for i in range(length))
我在代码中看到的get_random_secret_key 函数的唯一问题是允许的字符不包括大写字母,因此相同大小密钥的可能位数小于大写字母时的位数包括,但不多:
from math import log2
lower_plus_numbers = (list(chr(o) for o in range(0x61, 0x7B))
+ list(chr(o) for o in range(0x30, 0x3A)))
punctuation = list('!@#$%^&*(-_=+)')
upper_alpha = list(chr(o) for o in range(0x41, 0x5B))
shorter = log2((len(lower_plus_numbers) + len(punctuation)) ** 50)
longer = log2((len(lower_plus_numbers) + len(punctuation) + len(upper_alpha)) ** 50)
print(f'longer: {int(longer + 0.5)}; shorter: {int(shorter + 0.5)} '
f'difference: {int(longer - shorter + 0.5)}; ratio: {longer/shorter}')
以上代码的输出:
longer: 312; shorter: 282; difference: 30; ratio: 1.1070316647619918
所以,如果你有足够新的 Django 和 Python,最大的问题是你是想生成你的 SECRET_KEY 依赖于 Dango,还是只生成 Python。如果您不介意 Django 依赖,但想要包含大写字母,或者想要更长的键,您可以轻松地执行以下操作:
from django.utils.crypto import get_random_string
key_length = 60
get_random_string(
key_length,
allowed_chars=lower_plus_numbers + punctuation + upper_alpha,
)
样本输出:
'gW(VDtylhoAuZNcLbIC=ai5=2*tPZ=Gmf4D1^4T!NxX3tB0%_w7pYY2+FgDx'
如果您不想要 Django 依赖项,您可以使用 S Ghosh 的答案。或者,如果您想要的不仅仅是十六进制字符,您可以执行以下操作:
allowed_chars = [chr(i) for i in range(0x21, 0x7F)]
key_length = 60
key = ''.join(secrets.choice(allowed_chars) for i in range(key_length))
key 的值(作为 python 字符串):
'DN7tbWid#q6R^=%i"[1AA>$@AZg=XD+p|[aB?:#V`:kKWL77P6dC,~(\\9O\'j'