numpy randint() 生成字节

numpy randint() to generate bytes

我必须制作一个接收字节生成器输入的流密码(默认情况下 randint 函数)。我试图以这种方式实现它,但我不想在输出中有 str() 表示,我想要字节一,所以 b'\x.......').

我读到 bytes() 和整数列表给出了 str 表示,所以如果我 return cryptedcrypting_fn 中,用for 循环传给 bytes() 一次只有一个 int,我的“问题”能解决吗?如果没有,你能解释一下我该怎么做吗?

import numpy as np
import numpy.random


class SC(object):

    def __init__(self, key, prng=None, **kwargs):

        if prng is None:
            seed=None
            rs = np.random.RandomState(seed)
            def gen(seed):
                rs = np.random.RandomState(seed)
                while True:

                    yield rs.randint(0,255)

            self.prng = rs.randint(0, 255)

        else:
            self.prng = prng(key, **kwargs)


    def encrypt(self, plaintext):
        return self.crypting_fn(plaintext)

    def decrypt(self, ciphertext):
        return self.crypting_fn(ciphertext)

    def crypting_fn(self, text):

            crypted=bytes([b^s for b, s in zip(text, range(self.prng))])
            return crypted


message = 'hello world!'
key = 0x012345678

a = SC(key)
b = SC(key)

plaintextA = message.encode('utf-8')
ciphertext = a.encrypt(plaintextA)
plaintextB = b.decrypt(ciphertext)

print(plaintextA)
print(ciphertext)
print(plaintextB)

输出为:

b'hello world!'
b'hdnok%qhzen*'
b'hello world!'

您对 PRNG 的使用感到厌烦;您不是生成字节流,而是生成一个 单个 字节,并且您的密钥流只是 0、1、2、3...直到您命中随机字节(所以当字节很小,你甚至没有足够的加密整个输入)。

修正你的代码,使 self.prng 成为一个密钥流生成器,而不是单个随机字节,并照原样使用它,你会得到你想要的东西:

import numpy as np
import numpy.random


class SC(object):
    def __init__(self, key, prng=None, **kwargs):
        if prng is None:
            def gen(seed):
                rs = np.random.RandomState(seed)
                while True:
                    yield rs.randint(0, 255)

            self.prng = gen(key)  # Seed with provided "key", not None (which seeds from system random)
        else:
            # Without knowing what prng should be, I can't be sure this line is correct
            # This is what you'd want if calling prng produced an iterator using the keystream
            self.prng = prng(key, **kwargs)

    def encrypt(self, plaintext):
        return self.crypting_fn(plaintext)

    def decrypt(self, ciphertext):
        return self.crypting_fn(ciphertext)

    def crypting_fn(self, text):
        crypted=bytes([b^s for b, s in zip(text, self.prng)])
        return crypted

message = 'hello world!'
key = 0x012345678


a = SC(key)
b = SC(key)

plaintextA = message.encode('utf-8')
ciphertext = a.encrypt(plaintextA)
plaintextB = b.decrypt(ciphertext)

print(plaintextA)
print(ciphertext)
print(plaintextB)

输出:

b'hello world!'
b'+\x9f\xc8\xec\xd4\\xac\xf6\xae\xba\x9c\xeb'
b'hello world!'

Try it online!