簡體   English   中英

如果以前我使用隨機包在 python 中生成 unique_code ,那么使用秘密包的最佳方法是什么?

[英]What is the best way to use a secrets package, if previously I used a random package to generate unique_code in python?

我有這個生成unique_code的代碼

使用隨機包

import random

FullChar = 'CDHKPMQRVXY123456789'
total = 20
count = 7

for i in range(total):
        select = random.sample(FullChar, count)
        random.shuffle(select)
        unique_code = ''.join(select)
        print(entries)

我嘗試使用 Secrets 包

import random

FullChar = 'CDHKPMQRVXY123456789'
total = 20
count = 7

for i in range(total):
        select = random.sample(FullChar, count)
        select = secrets.SystemRandom.sample(FullChar, count)
        secrets.SystemRandom.shuffle(select)
        unique_code = ''.join(select)

這里我使用random包生成unique_code(import random),但我認為這是用這個包生成unique_code的舊方法,我想用secrets包生成unique_code(import secrets)。 使用秘密包(導入秘密)的最佳方法是什么,如果以前我使用隨機包生成像我之前編寫的代碼一樣的 unique_code ?

當我使用隨機包時它是清除的,但是當我將其更改為秘密包時它顯示錯誤

    select = secrets.SystemRandom.sample(FullChar, count)
TypeError: sample() missing 1 required positional argument: 'k'

謝謝

讓我們試試:

$ python3
Python 3.9.6 (default, Jul 16 2021, 00:00:00) 
>>> 
>>> import secrets
>>> count=5
>>> xs = list(range(20))
>>> 
>>> sel1 = secrets.SystemRandom.sample(xs, count)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sample() missing 1 required positional argument: 'k'
>>> 

問題重現。 但是只要位置參數的數量是錯誤的,Python 可能不會去抱怨其他任何事情。 所以讓我們提供任何額外的位置參數:

>>> 
>>> import math
>>> 
>>> sel1 = secrets.SystemRandom.sample(math.pi, xs, count)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.9/random.py", line 447, in sample
    randbelow = self._randbelow
AttributeError: 'float' object has no attribute '_randbelow'
>>> 

因此,從對某些_randbelow屬性的請求來看,Python 要求第一個位置參數是生成器。 我們只提供一個:

>>> 
>>> gen = secrets.SystemRandom()
>>> 
>>> sel1 = secrets.SystemRandom.sample(gen, xs, count)
>>> 
>>> sel1
[13, 16, 3, 15, 0]
>>> 
>>> gen.shuffle(sel1)
>>> 
>>> sel1
[15, 16, 3, 0, 13]
>>> 

所以現在看起來沒問題。

注:回想起來,似乎有點明顯。 如果您想要一些隨機子集,並且您已經提供了整個集合和您想要的元素數量,那么可能還缺少什么? 如果不是隨機數生成器。

jpmariner 到了那里,但它是通過奇怪地使用對象系統。 您只需要調用對象上的方法,例如:

from secrets import SystemRandom
# or alternatively
# from random import SystemRandom

full_char = 'CDHKPMQRVXY123456789'
count = 7

rng = SystemRandom()

for _ in range(20):
    letters = rng.choices(full_char, k=count)
    rng.shuffle(letters)
    print(''.join(letters)

將打印出 20 個密碼。 我進行了以下更改:使用choices來采樣“替換”,這對於更強的密碼是正確的(這使攻擊者更難)

注意: SystemRandomrandom模塊中定義,並且只是由secrets模塊重新導出,但是從secrets導入它可能會強調使用它的原因。 無論您從何處導入它,所有隨機性都來自系統的 CSPRNG,因此適用於加密目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM