如何将字节字符串转换为元组列表?
How to convert a byte string into a list of tuples?
我正在使用 pycryptodome
模块及其 AES 功能来加密一些数据。但是,我需要为以后可以检索的 AEScipher
生成一个密钥。该项目以图像的形式存储所有私有数据(包括密钥)。基本上我们使用像素数组并使用 PIL
创建图像并使用 getdata()
函数检索 pixel_list。
创建图像:-
array = numpy.array(pixels, dtype = numpy.uint8)
new_image = Image.fromarray(array)
new_image.save('user_key.png')
请注意,pixels 是一个 整数元组列表列表 [[(...), (...)], [(...), (...)], ...]
,这是携带键的对象
从图像中获取密钥:-
im = Image.open(image_path)
return list(im.getdata())
现在我无法直接存储 AES key
,假设我使用 Random.get_random_bytes(AES.key_size)
从 Crypto 模块生成它。
如何生成加密安全密钥,同时使用 pixels
中的其中一个密钥检索它,就像在整数元组中一样?
编辑:-
具体来说,像素对象是一个整数元组列表列表,每个元组包含3个整数,每个整数的范围是0到255。像素对象的第0个索引可能看起来像这样-
[(69, 147, 245), (120, 212, 198), ...]
我指的 key_list
对象实际上是 list(im.getdata())
。这是一个整数元组列表,每个元组包含 3 个整数,每个整数的范围从 0 到 255。这看起来像这样-
[(69, 147, 245), (120, 212, 198)....]
因此,key_list 的第 0 个索引将是 (69, 147, 245)
我需要存储与这些值相同的 AES 密钥。理想情况下,我希望将 AES 密钥存储为 0 到 255 之间的 3 个整数的元组。所以是的,我需要将 AES 密钥转换为元组,然后将其存储在 pixels
.
还有一个关键细节,元组包含 3 个整数,因为它们分别代表创建图像的 RGB 值。我相信元组也可以用 4 个整数来表示 RGBA 值。这样就解决了 3 的倍数问题。
但是还有一个问题。 pixels
中的每个元组实际上都是通过[i for i in itertools.product(range(256), repeat=3)]
生成的。为了生成一个包含 4 个整数而不是 3 个整数的元组,我必须将 repeat=3
更改为 repeat=4
,这将引发 MemoryError。
这是一个函数,可用于将字节字符串中的值划分为指定大小的元组。字节字符串首先作为整数列表打印出来,然后是与之对应的元组列表。请注意示例中最终元组除以 3 时的最后两个值是如何用零填充的,因为字节字符串长度 (16) 不是它的倍数。将它分成大小为 4 的元组时不会发生这种情况(因此没有附加填充值)。
另请注意,下面的 grouper()
函数与 itertools
documentation.
中同名配方的实现略有不同
from itertools import zip_longest
def grouper(n, iterable, fillvalue=None):
"s -> (s0, s1...sn-1), (sn, sn+1...s2n-1), (s2n, s2n+1...s3n-1), ..."
return zip_longest(*[iter(iterable)]*n, fillvalue=fillvalue)
aes_key = b'\x80in\xbe\x06b\x8f\x8fZ}l-\xb4j\xb5\x1f'
ints = list(aes_key)
print(ints)
tuples = list(grouper(3, aes_key, fillvalue=0))
print(tuples)
tuples = list(grouper(4, aes_key, fillvalue=0))
print(tuples)
输出:
[128, 105, 110, 190, 6, 98, 143, 143, 90, 125, 108, 45, 180, 106, 181, 31]
[(128, 105, 110), (190, 6, 98), (143, 143, 90), (125, 108, 45), (180, 106, 181), (31, 0, 0)]
[(128, 105, 110, 190), (6, 98, 143, 143), (90, 125, 108, 45), (180, 106, 181, 31)]
既然您想用这些数据制作图像,您可能仍需要进一步格式化该数据,具体取决于图像每行中的像素数。
您可以像这样将元组列表转换回字节字符串:
# To convert a list of tuples back into a byte string.
from itertools import chain
print(bytes(chain.from_iterable(tuples)))
输出:
b'\x80in\xbe\x06b\x8f\x8fZ}l-\xb4j\xb5\x1f'
但是,如果没有添加填充值(就像使用 4 元组的情况一样),这只会与原始字节字符串相同。
我正在使用 pycryptodome
模块及其 AES 功能来加密一些数据。但是,我需要为以后可以检索的 AEScipher
生成一个密钥。该项目以图像的形式存储所有私有数据(包括密钥)。基本上我们使用像素数组并使用 PIL
创建图像并使用 getdata()
函数检索 pixel_list。
创建图像:-
array = numpy.array(pixels, dtype = numpy.uint8)
new_image = Image.fromarray(array)
new_image.save('user_key.png')
请注意,pixels 是一个 整数元组列表列表 [[(...), (...)], [(...), (...)], ...]
,这是携带键的对象
从图像中获取密钥:-
im = Image.open(image_path)
return list(im.getdata())
现在我无法直接存储 AES key
,假设我使用 Random.get_random_bytes(AES.key_size)
从 Crypto 模块生成它。
如何生成加密安全密钥,同时使用 pixels
中的其中一个密钥检索它,就像在整数元组中一样?
编辑:-
具体来说,像素对象是一个整数元组列表列表,每个元组包含3个整数,每个整数的范围是0到255。像素对象的第0个索引可能看起来像这样-
[(69, 147, 245), (120, 212, 198), ...]
我指的 key_list
对象实际上是 list(im.getdata())
。这是一个整数元组列表,每个元组包含 3 个整数,每个整数的范围从 0 到 255。这看起来像这样-
[(69, 147, 245), (120, 212, 198)....]
因此,key_list 的第 0 个索引将是 (69, 147, 245)
我需要存储与这些值相同的 AES 密钥。理想情况下,我希望将 AES 密钥存储为 0 到 255 之间的 3 个整数的元组。所以是的,我需要将 AES 密钥转换为元组,然后将其存储在 pixels
.
还有一个关键细节,元组包含 3 个整数,因为它们分别代表创建图像的 RGB 值。我相信元组也可以用 4 个整数来表示 RGBA 值。这样就解决了 3 的倍数问题。
但是还有一个问题。 pixels
中的每个元组实际上都是通过[i for i in itertools.product(range(256), repeat=3)]
生成的。为了生成一个包含 4 个整数而不是 3 个整数的元组,我必须将 repeat=3
更改为 repeat=4
,这将引发 MemoryError。
这是一个函数,可用于将字节字符串中的值划分为指定大小的元组。字节字符串首先作为整数列表打印出来,然后是与之对应的元组列表。请注意示例中最终元组除以 3 时的最后两个值是如何用零填充的,因为字节字符串长度 (16) 不是它的倍数。将它分成大小为 4 的元组时不会发生这种情况(因此没有附加填充值)。
另请注意,下面的 grouper()
函数与 itertools
documentation.
from itertools import zip_longest
def grouper(n, iterable, fillvalue=None):
"s -> (s0, s1...sn-1), (sn, sn+1...s2n-1), (s2n, s2n+1...s3n-1), ..."
return zip_longest(*[iter(iterable)]*n, fillvalue=fillvalue)
aes_key = b'\x80in\xbe\x06b\x8f\x8fZ}l-\xb4j\xb5\x1f'
ints = list(aes_key)
print(ints)
tuples = list(grouper(3, aes_key, fillvalue=0))
print(tuples)
tuples = list(grouper(4, aes_key, fillvalue=0))
print(tuples)
输出:
[128, 105, 110, 190, 6, 98, 143, 143, 90, 125, 108, 45, 180, 106, 181, 31]
[(128, 105, 110), (190, 6, 98), (143, 143, 90), (125, 108, 45), (180, 106, 181), (31, 0, 0)]
[(128, 105, 110, 190), (6, 98, 143, 143), (90, 125, 108, 45), (180, 106, 181, 31)]
既然您想用这些数据制作图像,您可能仍需要进一步格式化该数据,具体取决于图像每行中的像素数。
您可以像这样将元组列表转换回字节字符串:
# To convert a list of tuples back into a byte string.
from itertools import chain
print(bytes(chain.from_iterable(tuples)))
输出:
b'\x80in\xbe\x06b\x8f\x8fZ}l-\xb4j\xb5\x1f'
但是,如果没有添加填充值(就像使用 4 元组的情况一样),这只会与原始字节字符串相同。