gpt4 book ai didi

python - 加密安全伪随机洗牌 python 中的列表或数组

转载 作者:行者123 更新时间:2023-12-04 17:20:24 25 4
gpt4 key购买 nike

我需要一个使用 CSPRNG(加密安全伪随机数生成器)的洗牌函数,并且可以手动播种相同种子的相同输出。

内置的random.shuffle() in Python可以手动播种但是是 not suitable for cryptographic use并将在 python 3.11 版本中删除。

Crypto.Random.random.shuffle() from PyCryptodome不接受我能收集到的种子。

目前,我已经解决了内置 random.shuffle() 函数使用的 Mersenne Twister 来随机排列数字列表的问题,但这远非理想。作为内置的 numpy.random.shuffle is not suitable for cryptographic purposes 也欢迎打乱 numpy 数组。 .数组/列表可能包含超过 100 亿个元素,因此性能和随机性是关键。

创可贴代码如下。

import numpy as np
from random import seed, shuffle
array = np.arange(10) # [0 1 2 3 4 5 6 7 8 9]
print(array)
seed(1)
shuffle(array)
print(array) # [6 8 9 7 5 3 0 4 1 2]

最佳答案

CSPRNG 通常会遇到重新播种等问题,在操作期间从操作系统内的熵池中提取熵。因此,最好使用流密码,例如AES 计数器模式。

那么洗牌操作始终以相同的方式执行也很重要。同样,生成的比特流中的数字应始终以相同的方式运行。如果对这些进行了优化或以其他方式更改,结果将是不同的洗牌,从而破坏了方案。

最后你最好自己编程,这样你就可以确定方法契约背后的代码不会改变。

这方面的要求是:

  • 带有 key 大小的种子的流密码;
  • 实现“拒绝抽样”以获取范围内的随机数;
  • Fisher-Yates 洗牌以创建完全随机的洗牌。

如果大小不符合流密码,则可以对种子进行哈希处理并取最左边的字节。


想法的演示(未经过全面测试或精心设计):

import numpy as np
from Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes

array = np.arange(100) # [0 1 2 3 4 5 6 7 8 9]

seed = bytes([0x00]) * 32 # use SHA-256 to hash different size seeds

nonce_rfc7539 = bytes([0x00]) * 12
cipher = ChaCha20.new(key=seed, nonce=nonce_rfc7539)
zerobuf = bytes([0x00]) * 5

def sample(max):
# rejection sampling using rand(0..n * max) % max
# the value 2 is in there to make sure the number of bits is at least
# two higher than max, so that the chance of each candicate succeeding
# is higher
stream_size = (max.bit_length() + 2 + 7) // 8
max_stream_value = 1 << (stream_size * 8)
max_candidate = max_stream_value - max_stream_value % max
while True:
stream = cipher.encrypt(zerobuf[0:stream_size])
candidate = int.from_bytes(stream, "big")
if (candidate < max_candidate):
break
return candidate % max

def shuffle(list):
# do the Fisher-Yates shuffle
for i in range(len(list) - 1, 0, -1):
j = sample(i + 1)
list[i],list[j] = list[j],list[i]

# test only
print(array)
for i in range(0, 100):
shuffle(array)
print(array)

关于python - 加密安全伪随机洗牌 python 中的列表或数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66528995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com