问题
I am trying to test create a simple cipher that xor key with a bitmap image.
import os, io, hashlib
from PIL import Image
from array import array
from itertools import cycle
key = "aaaabbbb"
def generate_keys(key):
round_keys = hashlib.md5(key).digest()
return bytearray(round_keys)
def readimage(path):
with open(path, "rb") as f:
return bytearray(f.read())
def generate_output_image(input_image, filename_out):
output_image = Image.open(io.BytesIO(input_image))
output_image.save(filename_out)
def xor(x,y):
return [ a ^ b for a,b in zip(x,cycle(y))]
round_keys = generate_keys(key)
input_image = readimage("lena512.bmp")
encrypted_image = xor(input_image, round_keys)
generate_output_image(encrypted_image, "lena_encrypted.bmp")
input_image = readimage("lena_encrypted.bmp");
decrypted_image = xor(input_image, round_keys)
generate_output_image(decrypted_image, "lena_decrypted.bmp")
But I'm getting the following error when I run the script:
Traceback (most recent call last):
File "test.py", line 26, in <module>
generate_output_image(encrypted_image, "lena_encrypted.bmp")
File "test.py", line 17, in generate_output_image
output_image = Image.open(io.BytesIO(input_image))
TypeError: 'list' does not have the buffer interface
How do I convert the byte array back into bitmap image? Any help would be appreciated thanks.
回答1:
Updated script thats convert plain image to cipher image and back to plain image.
import os, io, hashlib, math, binascii
from PIL import Image
from array import array
from itertools import cycle
user_key = "aaaabbbb"
test_image = "lena512.bmp"
def generate_keys(key):
round_keys = hashlib.md5(key).digest()
return bytearray(round_keys)
def readimage(path):
with open(path, "rb") as f:
return bytearray(f.read())
def generate_output_image(input_image):
output_image = Image.open(io.BytesIO(input_image))
output_image.save(test_image)
def xor(x,y):
return x[:54] + bytearray([a^b for a, b in zip(x[54:], cycle(y))])
round_keys = generate_keys(user_key)
input_image = readimage(test_image)
encrypted_image = xor(input_image, round_keys)
generate_output_image(encrypted_image)
input_image = readimage(test_image);
decrypted_image = xor(input_image, round_keys)
generate_output_image(decrypted_image)
Thanks myrmica for your help
回答2:
I looked a bit more into how to retrieve/update the image data more elegantly with the tools included in PIL/Pillow, and made this simple working example:
from PIL import BmpImagePlugin
import hashlib
from itertools import cycle
keys = hashlib.md5(b"aaaabbbb").digest()
input_image = BmpImagePlugin.BmpImageFile("img/tea.bmp")
# extract pure image data as bytes
image_data = input_image.tobytes()
# encrypt
image_data = bytes(a^b for a, b in zip(image_data, cycle(keys)))
# create new image, update with encrypted data and save
output_image = input_image.copy()
output_image.frombytes(image_data)
output_image.save("img/tea-encrypted.bmp")
This way, you don't have to worry about the BMP header size.
(links: original and encrypted image)
来源:https://stackoverflow.com/questions/53673126/how-do-i-convert-byte-array-to-bitmap-image-in-python