Descripción:
Ocultar un mensaje (secreto) dentro de otro (público), por ejemplo archivos de imagen,
sonido, etc.
Intentando no afectar a la estadística propiedades del mensaje público con el fin de evitar la
detección.
detección.
para ocultar información:
python esteganografia.py imagen.ext -o
para descifrar el mensaje oculto:
python esteganografia.py imagen.ext -d
de preferencia .ext = .png .tiff .bmp con los archivos con formato ,jpg no funcionara.
from PIL import Image
from sys import argv
'''Convierte el Mensaje a binario'''
''' Convierte binario cada letra en el string,
omite los espacios 'b' y toma solo de 8-bits
para representar el valor de la letra en binario'''
def strToNumToBin(string):
'''recorre el string y va convirtiendo caracter en caracter en numero y despues en binario'''
return [bin(ord(caracter))[2:].zfill(8) for caracter in string] #devuelve el arreglo[]
'''URL:http://code.activestate.com/recipes/578291-string-to-binary/ @Shawn'''
'''Convierte Binario a String'''
def binToNumToStr(binario):
'''recorrre la cadena binaria bit por bit convirtiendo en numero y despues en string :3'''
return [chr(int(bit,2)) for bit in binario] #devuelve el arreglo[] :')
'''Ejemplo :B binario (oviusly base 2) a numero y de numero a caracter
probar en interprete de python :3
>>chr(int('10011010',2))'''
def main():
entrada= None
comando= None
try:
'''Intenta tomar los argumentos de entrada'''
imagen = argv[1]
comando = argv[2]
except:
'''Si no los recibio correctamente los pregunta interactivamente'''
imagen = raw_input('Archivo de Imagen: ')
comando = raw_input('-d para decifrar el mensaje oculto \t -o para ocultar mensaje: ')
data = Image.open(imagen).convert('RGB') #abre imagen de acuerdo a la entrada
'''Comando para Ocultar el mensaje dentro de la imagen'''
if comando == '-o':
(w, h) = data.size #tamanio de imagen
resultado = Image.new('RGB', (w, h)) #asigna a resultado los datos de la imagen original
nuevo = resultado.load() #carga resultado a nueva imagen que generamos
pixel = data.load() #carga pixeles
'''Entrada de Mensaje '''
mensaje = raw_input('Mensaje a Ocultar:')
bits=[] #cadenita de bits donde se alojara el numero en binario de el largo del mensaje
for caracter in mensaje: #checa cada caracter en el mensaje
bits+= strToNumToBin(caracter) # y acumula cuantos lleva
largo = len(bits) #con esto definimos el largo del mensaje
cosabin= strToNumToBin(mensaje)#convierte el mensaje en binario
c = 0 #contador
for x in xrange(w): #recorre la imagen
for y in xrange(h): # base por altura :3 (w,h) ,i think
r, g, b = pixel[x, y] #los pixeles adquieren coordenadas
if c < largo: #recorremos el num binario del largo del mensaje bit por bit
if (int(bits[c]) % 2) == 0:
if b % 2 == 1:#IMPAR cuando es impar c:
b = 0 #y si el canal azul es impar le asigna uno
if b>254: #si se pasa de los 254 que es su color
b=253 #le restamos para que este dentro de los rangos #no estoy segura que funcione ._.
elif b<0: #si no alcanza el minimo para ser un color
b=1 #se queda en 1 dentro de color azul
else:
if b % 2 == 0:#PAR
b = 1 #y si el canal azul es impar se le asigna uno
if b>254: #si se pasa de los 254 que es su color
b=253 #le restamos para que este dentro de los rangos #no estoy segura que funcione ._.
nuevo[x, y] = r, g, b
c += 1
print bits#numero en binario del largo del mensaje
print largo#numero del largo en decimal ._.
#if cosabin == mensaje LOAD :D
print cosabin#imprime el mensaje en binario
print mensaje#imprime el mensaje original
#procederiamos a ocultarlo :B
resultado.save(imagen[:imagen.index('.')]+'copy'+imagen[imagen.index('.'):],'PNG')
resultado.show()
else:
if comando == '-d':
(w, h) = data.size #tamanio de imagen
#aqui debe de hacer lo contrario convertir binario a string
#y luego comparar y Done... :3
#print binToNumToStr(cosabin)
#print "".join(binToNumToStr(cosabin))
#for x in xrange(w):
#for y in xrange(h):
#r, g, b = pixel[x, y]
#nuevo[x, y] = r, r, 0
#b=1#aqui aun no se que pedo
print 'ya'
else:
print 'comando no valido, empecemos de nuevo.'
main()
if __name__ == '__main__':
main()
''' Al llamar a al programa la sintaxis para que funcione
a partir de argumentos de programa es la siguiente:
esteganografia.py imagen.extencion -comando
donde:
extencion = .png /.tiff /.bmp
y comando = -o / -d '''
Referencias
La explicación está un poco pobre y hay algunas confusiones en el código. El principio de todo parece más o menos decente. Van 6 pts por el avance parcial.
ResponderBorrar