I have created a small cryptographic programme:
- You input your text
- A random image is generated
- Random coordinate pairs in number equal to the chars of the message are generated.
- The red component of the points at the coordinates given above is modified to become equal to the ASCII value of the letter.
- The text can now be read only knowing which points actually encode the letters and which other points are just noise.
Can you tell me any flaws in the approach that would make my message crackable (having only the image and not knowing the key used)?
If you are wondering about the implementation details, the actual programme is provided down below:
from __future__ import print_function
from PIL import Image
import random
SIZE = 500
MESSAGE = "Boh i don't know what I know to be knowing"
RELEVANT_POSITIONS = [(random.randint(0,SIZE),random.randint(0,SIZE)) for _ in range(len(MESSAGE))]
FILENAME = "Crypted.png"
IMAGE = Image.new("RGB", (SIZE,SIZE))
def from_letter_to_colour(letter):
value = ord(letter)
return (value,random.randint(0,256),random.randint(0,256))
def from_colour_to_letter(colour):
return chr(colour[0])
def draw(position,colour):
IMAGE.putpixel(position,colour)
def random_colour():
return (random.randint(1,256),random.randint(1,256),random.randint(1,256))
def all_positions():
return ( (x,y) for x in range(SIZE) for y in range(SIZE) )
def get_pixels(image_name):
image = Image.open(image_name)
pixels = image.load()
return pixels
def create_random_image():
for position in all_positions():
draw(position,random_colour())
def encode_message(message):
create_random_image()
for index,position in enumerate(RELEVANT_POSITIONS):
try:
draw(position,from_letter_to_colour(message[index]))
except IndexError:
break
IMAGE.save(FILENAME)
def test_encode_decode():
for char in ( chr(i) for i in range(1,128)):
assert from_colour_to_letter(from_letter_to_colour(char)) == char
def decode_message():
message = []
pixels = get_pixels(FILENAME)
for position in RELEVANT_POSITIONS:
x,y = position
message.append(from_colour_to_letter(pixels[x,y]))
return ''.join(message)
def main():
print("The key is: {}".format(RELEVANT_POSITIONS))
encode_message(MESSAGE)
print(decode_message())
if __name__ == "__main__":
test_encode_decode()
main()