在Python中编码元组或字典?

问题描述 投票:0回答:2

我正在使用加密模块加密一些数据,然后尝试将其存储在我的 SQL 数据库中。当它是一个字符串时,它就起作用了。但是,当我尝试使用元组或字典时,它失败了。我有以下作为我正在调用的函数。 (使用 cryptotography.Fernet.encrypt)。

def encrypt(to_encrypt):
    ''' Takes a bytestring and returns a token. '''
    key = get_key()
    f = make_fernet_object(key)
    token = f.encrypt(to_encrypt)
    return token

如果我尝试直接将元组或字典传递给它,我会得到

类型错误:数据必须是字节。

如果我使用

bytes(my_tuple)

然后我明白了

类型错误:“str”对象无法解释为整数

如何将我的元组(包含 2 个字符串和一个字典)转换为 Fernet 将加密的字节对象,以便我可以将 blob 放入我的 SQL 数据库中?

编辑 - 有问题的元组的格式为..

my_tuple = ('username', 'password', {'memorable question':'memorable answer', 'memorable question 2', 'memorable answer 2'})
python python-3.x dictionary tuples byte
2个回答
1
投票

正如您的错误消息所示,

encrypt
仅接受字节作为输入。您可以将字符串格式化为字节,但不能将元组格式化,元组是 Python 对象的序列。您可以将元组中包含的两个字符串中的任何一个传递给
bytes()
,或者将它们分隔并连接为单个字符串并传递它,但不能传递元组本身(不指定将其转换为字符串并恢复的方法)表示字符串作为元组)。

https://cryptography.io/en/latest/_modules/cryptography/fernet/


0
投票

我假设您的数据是强类型的
喜欢

tuple[str, str, dict[str, str]]

在这种情况下,这可能会有所帮助(如果没有,也许会有所帮助,但更难)
我定义了一个可以序列化字节可迭代的类(我将它放在底部)
它只是(反)序列化多个东西,你只需要告诉它要序列化什么
然后你可以在你的情况下使用它,比如

obj = my_tuple = ('username', 'password', {'memorable question':'memorable answer', 'memorable question 2': 'memorable answer 2'})
serialized = ArgsToBytes.argsToBytes(serializeStr(obj[0]), serializeStr(obj[1]), ArgsToBytes.argsToBytes(*(ArgsToBytes.argsToBytes(serializeStr(k), serializeStr(v)) for (k, v) in obj[2].items())))
# serialized == b'8:username8:password96:42:18:memorable question16:memorable answer0:46:20:memorable question 218:memorable answer 20:0:0:'
a = ArgsToBytes.bytesToArgs(serialized)
# a == [b'username', b'password', b'42:18:memorable question16:memorable answer0:46:20:memorable question 218:memorable answer 20:0:']
b = ArgsToBytes.bytesToArgs(a[2])
# b == [b'18:memorable question16:memorable answer0:', b'20:memorable question 218:memorable answer 20:']
c = dict(ArgsToBytes.bytesToArgs(x) for x in b)
#c == {b'memorable question': b'memorable answer', b'memorable question 2': b'memorable answer 2'}

如你所见,这里写得有点多了
理想情况下,您可以将事物分为类和函数

class ArgsToBytes:
    @staticmethod
    def argsToBytes(*args) -> bytes:
        serialized = b"";
        for arg in args:
            if not isinstance(arg, bytes): arg = bytes(arg);
            length = len(arg);
            serialized += str(length).encode("ascii") + b":" + arg;
        pass
        serialized += b"0:";
        return serialized;
    pass
    @staticmethod
    def bytesToArgs(serialized: bytes) -> list:
        result = [];
        i = 0;
        while True:
            index = serialized.index(b":", i);
            length = serialized[i : index];
            i = index + 1;
            length = int(length.decode("ascii"));
            if length == 0: break;
            index = i + length;
            result.append(serialized[i : index]);
            i = index;
        pass
        return result;
    pass
pass
© www.soinside.com 2019 - 2024. All rights reserved.