Here's my code in three of the six photos. I recommend to download these photos from the link below because blogspot changes something and it's difficult to recover the information.
After the deadline, I'm going to explain how my algorithm works.
Parameters to encrypt:
1.- Name of the text to encrypt
2.- The image to hide the message
3.- The name of the image with the message
Example:
imagenes.py photo8.bmp copia8.bmp
Parameters to decrypt:
1.- Name of the image with the message
2.- The file to put the message
3.- The keyword "decripta"
Example:
copia6.bmp recuperado6.dat decripta
Código
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#parameters to encrypt | |
# name of the text to encrypt, the image and the name of the image with the message | |
# example | |
# imagenes.py photo8.bmp copia8.bmp | |
# | |
#parameters to decrypt | |
# the name of the image with the message, the file to put the message and the keyword "decripta" | |
# example | |
# copia6.bmp recuperado6.dat decripta | |
import Image | |
import binascii | |
import numpy as np | |
from PIL import ImageDraw | |
from sys import argv | |
from math import sqrt, ceil | |
from random import random | |
def receivePlaintext(message): | |
bin_message = '' | |
aux = '' | |
for m in message: | |
aux = bin(int(binascii.hexlify(m), 16))[2:] | |
while len(aux) < 7: | |
aux = '0' + aux | |
bin_message += aux | |
return bin_message | |
def receiveLengthtext(message): | |
l_message = bin(int(binascii.hexlify(message), 16))[2:] | |
return l_message | |
def receiveBinarytext(b): | |
s = '%x' % (int('0b' + b, 2)) | |
while len(s) < 2: | |
s = '0' + s | |
return binascii.unhexlify(s) | |
def positions(w, h, n): | |
pixels = list() | |
k = int(ceil(sqrt(n))) | |
dx = w / (k + 1) | |
dy = h / (k + 1) | |
for i in xrange(k): | |
x = (i + 1) * dx | |
for j in xrange(k): | |
y = (j + 1) * dy | |
pixels.append((x, y)) | |
return pixels | |
def getMessage(image): | |
im = Image.open(image) | |
message = list() | |
width, height = im.size | |
im = im.convert('RGB') | |
pix = im.load() | |
message= '' | |
character = '' | |
eachNum = '' | |
large = '' | |
for x in xrange(width): | |
r, g, b = pix[x, 1] | |
if g % 2 == 0 and b % 2 == 0: | |
eachNum+='0' | |
print "Encontre 0" | |
if g % 2 != 0 and b % 2 != 0: | |
eachNum+='1' | |
print "Encontre 1" | |
if g % 2 == 0 and g % 2 !=0: | |
break | |
if g % 2 != 0 and g % 2 == 0: | |
break | |
print large | |
large = receiveBinarytext(eachNum) | |
print "Largo del mensaje ",large | |
large = int(large) | |
pos = positions(width, height, large) | |
for (x, y) in pos: | |
r, g, b = pix[x, y] | |
if r % 2 == 0: # 1 para impares y 0 para pares | |
character += '0' | |
else: | |
character += '1' | |
print 'Obtuvo con (%d, %d, %d) en (%d, %d) un bit %s' % (r, g, b, x, y, character[-1]) | |
if len(character) == 7: | |
if '1' in character: | |
c = receiveBinarytext(character) | |
message += c | |
character = '' | |
return message | |
def perturbacion(color, b): | |
bit = int(b) | |
if bit == (color % 2): | |
return color | |
#print bit, (color % 2) | |
diff = 1 | |
if random() > 0.5: | |
diff *= -1 | |
color += diff | |
#print bit, (color % 2) | |
if color > 255: | |
color -= 2 | |
elif color < 0: | |
color += 2 | |
#assert(bit == (color % 2)) | |
#print 'color %d' % color | |
return color | |
def setMessage(message, image, copy): | |
n = len(message) * 7 | |
im = Image.open(image) | |
width, height = im.size | |
print width, height | |
im = im.convert('RGB') | |
pix = im.load() | |
pos = positions(width, height, n) | |
bits = receivePlaintext(message) | |
while len(bits) < len(pos): | |
bits += '0' | |
i = 0 | |
for (x, y) in pos: | |
r, g, b = pix[x, y] | |
bit = bits[i] | |
#print 'Poniendo con (%d, %d, %d) en (%d, %d) un bit %s' % (r, g, b, x, y, bit) | |
pix[x, y] = perturbacion(r, bit), g, b | |
print 'Queda con (%d, %d, %d) en (%d, %d) un bit %s' % (r, g, b, x, y, bit) | |
i += 1 | |
# for (x, y) in pos: | |
# print 'Array tiene %s en (%d, %d)' % (data[y, x], x, y) | |
num = receiveLengthtext(str(n)) | |
print "n ",num | |
print "n[0] ",num[0] | |
print "len(n)",len(num) | |
aux = 0 | |
for x in xrange(width): | |
r, g, b = pix[x, 1] | |
if(len(num) > aux): | |
print aux | |
if num[aux] == '0': | |
print "pongo 0*" | |
if g % 2 != 0: | |
g-=1 | |
if b % 2 != 0: | |
b-=1 | |
if num[aux] == '1': | |
print "pongo 1*" | |
if g % 2 == 0: | |
g+=1 | |
if b % 2 == 0: | |
b+=1 | |
else: | |
if g % 2 == 0 and b % 2 == 0 : | |
print "pongo nada" | |
g += 1 | |
if g % 2 != 0 and b % 2 != 0 : | |
print "pongo nada" | |
g -= 1 | |
aux+=1 | |
pix[x, 1] = r, g, b | |
data = np.array(im) | |
print data.shape | |
im2 = Image.fromarray(data) | |
im2.save(copy) | |
return n | |
def main(): | |
if argv[3] == 'decripta': | |
recover = getMessage(argv[1]) | |
result = open(argv[2], 'w') | |
print >>result, recover.strip() | |
result.close() | |
return | |
else: | |
message = open(argv[1], 'r') | |
msg = ''.join(message.readlines()) | |
message.close() | |
n = setMessage(msg, argv[2], argv[3]) | |
print 'Message of length %d hidden.' % n | |
return | |
print 'o_0' | |
return | |
main() |
**Note** The three images with message are the number 1, 3 and 5.
El programa no sabe decir cuáles parámetros quiere. Si no hay mensaje, sale mugrero. Van 9 pts.
ResponderEliminar