一把钥匙作为种子,如何洗牌和解牌

2024-09-30 01:28:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个加密系统,为此我将采用bytearray,并打算使用

random.Random(seed).shuffle(bytearray)

函数对信息进行加密

我在反转此过程进行解密时遇到问题,我尝试了类似(无效)的方法:

random.Random(1/seed).shuffle(encryptedbytearray)

有什么办法可以这样做吗


Tags: 方法函数信息过程系统randomseedshuffle
2条回答

洗牌排序范围,以便我们可以将洗牌标记与未洗牌标记相匹配

x = list(range(len(s)))
random.Random(seed).shuffle(x)

对于12345的种子,这将产生[14, 15, 12, 3, 24, 16, 7, 22, 10, 2, 19, 4, 20, 17, 1, 21, 5, 25, 18, 8, 6, 11, 9, 0, 23, 13]。这表示无序列表的第0个索引中的值实际上在未缓冲列表的第14个索引中,第1个索引实际上是第15个未缓冲列表,以此类推

然后将每个无序索引与无序值匹配,然后(基于索引)排序回其未无序位置

unshuffled = bytearray(c for i, c in sorted(zip(x, s)))
print(unshuffled)

完整示例:

import random
# setup
s = bytearray(b"abcdefghijklmnopqrstuvxwyz")
seed = 12345
random.Random(seed).shuffle(s)

# shuffle a sorted range, so that we can match the shuffled indicies to the unshuffled indicies
x = list(range(len(s)))
random.Random(seed).shuffle(x)

# match each shuffled index to the shuffled value, and then sort (based on the index) back into their unshuffled positions
unshuffled = bytearray(c for i, c in sorted(zip(x, s)))
print(unshuffled)

上面详述的过程应该适用于任何无序序列(例如列表),而不仅仅是ByteArray

这里是a more detailed explanation of this process on crypto.se,涉及的数学要多得多

您需要使用相同的种子来洗牌索引,以便可以回溯原始位置。(enumerate将允许您避免对该映射进行排序)

import random

def encrypt(decrypted,seed=4):
    encrypted = decrypted.copy()
    random.Random(seed).shuffle(encrypted)
    return encrypted

def decrypt(encrypted,seed=4):
    decrypted = encrypted.copy()
    indexes   = list(range(len(encrypted)))
    random.Random(seed).shuffle(indexes)
    for e,d in enumerate(indexes):
        decrypted[d] = encrypted[e]
    return decrypted

示例运行(使用字符列表,但适用于ByteArray或任何其他类型的列表):

clearText = list('ABCDE')

encryptedText = encrypt(clearText)
print(encryptedText)
['D', 'E', 'A', 'C', 'B']

decryptedText = decrypt(encryptedText)
print(decryptedText)
['A', 'B', 'C', 'D', 'E']

如果希望函数直接在数组上“就地”工作(而不是返回值),可以这样编写它们:

def encrypt(decrypted,seed=4):
    random.Random(seed).shuffle(encrypted)

def decrypt(encrypted,seed=4):
    before   = encrypted.copy()
    indexes  = list(range(len(encrypted)))
    random.Random(seed).shuffle(indexes)
    for e,d in enumerate(indexes):
        encrypted[d] = before[e]

相关问题 更多 >

    热门问题