I'm trying to code LSB steganography method via numpy arrays. I got code which makes the bool index mask, which will give those bits of red channel, which need to xor with 1.
import numpy as np
from scipy.misc import imread
import matplotlib.pyplot as plt
message = 'Hello, World!'
message_bits = np.array(map(bool, map(int, (''.join(map('{:b}'.format, bytearray(message)))))), dtype=np.bool)
img = imread('screenshot.png')
xor_mask = np.zeros_like(img, dtype=np.bool)
ind = 0
for j, line in enumerate(xor_mask):
for i, column in enumerate(line):
if ind < len(message_bits):
xor_mask[j, i, 0] = message_bits[ind]
ind += 1
else:
break
else:
continue
break
img[xor_mask] ^= 1
Is there more compact way to construct the xor_mask? Maybe through numpy broadcast
UPD: Reduced my for-loop to this:
for j, line in enumerate(xor_mask):
if ind < len(message_bits):
xor_mask[j, :, 0] = message_bits[ind]
ind += len(xor_mask[j])
else:
break
If you pad message_bits
to have as many elements as pixels in xor_mask
then it gets simple:
xor_mask = np.zeros_like(img, dtype=np.bool)
xor_mask[:, :, 0] = np.reshape(message_bits, xor_mask.shape[:2])
Another way, without padding:
xor_mask[:, :, 0].flat[:len(message_bits)] = message_bits