Steganography
Cryptography can be used to make the contents of a message secret, but sometimes you want to hide that a message is even being sent. Steganography is one way to hide messages, and a common technique takes advantage of our inability to perceive small changes in colors. For example the image below consists of two boxes with different colors.

The left box has the RGB values (161, 187, 150). The box on the right has the RGB values (162, 188, 151). The two boxes appear to be the same color because the RGB values are similar. A message can be hidden in an image by making small changes to the RGB values of an existing image.
A common way of modifying an image is to change only the least significant bits of the RGB values. The least significant bit of a number is the right-most bit. Therefore, the most a color value will change if the least significant bit is change is 1, which the above image demonstrates as imperceptible. The following whale image, for example, has a message encoded in it.

Details
Create a program that prints the secret message that is embedded in an image file. The message is encoded as 8-bit ASCII in the least significant bit of the image's color data. Assume that the number of color values in the file is a factor of 8. Once you have tested your program on a simple example, you can test it on the above whale image.
Some things to keep in mind:
- Each color in a pixel encodes a single bit. Extract the least significant bit of each of these values.
- The bits of the hidden message are in row-order. This means that the pixels of the image should be processed starting in the upper-left corner of the image (row = 0, col = 0) and proceeding right. When the end of a row is reached, process the next row down.
- Once you have processed 8 color values, you will have to convert the binary sequence represented by their least significant bits into a single character. This is one character in the hidden message.
-
You can use the built-in
int
function to convert a binary string into an int using the optionalbase
parameter. For example,int('00010011', base=2)
.
Example
The pixels:
[[[122, 101, 215], [42, 2, 128], [200, 13, 64], [203, 155, 130], [36, 172, 91], [180, 88, 77], [55, 22, 44], [66, 33, 99]]]
have the least significant bits:
01100001 01100010 01100011
and encode the text:
abc
Hint
- Use the accumulator pattern for strings, accumulating the least significant bit of the color values into a string. A number that is odd has a 1 as the least significant bit, a number that is even has a 0 as the least significant bit.
-
Convert a binary string to a base-10 integer by using the
built-in
int
function. -
Convert an integer to a character using the
built-in
chr
function.
Challenge
Write a program that can embed messages into images. The program should read a message, an input image file name. It should read in the input image, modify the least significant bits of the color values to embed the message, and write the new image to a new file.