monkey-storage / monkey.py
Bart6114's picture
finished poc?
94241e7
"""
Note, this heavily builds upon
https://gist.github.com/goelashwin36/6847a974c9b7b2ca500154d5c89d1d76
"""
from email.mime import base
import glob
import random
from PIL import Image
def random_base_img():
img_fn = random.choice(glob.glob("./base_images/*.jpg"))
return Image.open(img_fn, "r")
def modify_pixel(pixel, data):
data_lst = [format(ord(d), "08b") for d in data]
data_len = len(data_lst)
imdata = iter(pixel)
for i in range(data_len):
pix = [
value
for value in imdata.__next__()[:3]
+ imdata.__next__()[:3]
+ imdata.__next__()[:3]
]
# Pixel value should be made
# odd for 1 and even for 0
for j in range(0, 8):
if data_lst[i][j] == "0" and pix[j] % 2 != 0:
pix[j] -= 1
elif data_lst[i][j] == "1" and pix[j] % 2 == 0:
if pix[j] != 0:
pix[j] -= 1
else:
pix[j] += 1
# Eighth pixel of every set tells
# whether to stop ot read further.
# 0 means keep reading; 1 means thec
# message is over.
if i == data_len - 1:
if pix[-1] % 2 == 0:
if pix[-1] != 0:
pix[-1] -= 1
else:
pix[-1] += 1
else:
if pix[-1] % 2 != 0:
pix[-1] -= 1
pix = tuple(pix)
yield pix[0:3]
yield pix[3:6]
yield pix[6:9]
def encode(data):
base_img = random_base_img()
w = base_img.size[0]
(x, y) = (0, 0)
for pixel in modify_pixel(base_img.getdata(), data):
base_img.putpixel((x, y), pixel)
if x == w - 1:
x = 0
y += 1
else:
x += 1
return base_img.copy()
def decode(img):
data = ""
imgdata = iter(img.getdata())
while True:
pixels = [
value
for value in imgdata.__next__()[:3]
+ imgdata.__next__()[:3]
+ imgdata.__next__()[:3]
]
# string of binary data
binstr = ""
for i in pixels[:8]:
if i % 2 == 0:
binstr += "0"
else:
binstr += "1"
data += chr(int(binstr, 2))
if pixels[-1] % 2 != 0:
return data