martes, 9 de julio de 2013

Esteganografía [programa 4 [P4]]

Tarea Realizada para la Materia de Seguridad de la información y criptografía Esteganografía[Programa 4 [P4]].



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.


Al ejecutar el código se necesita la siguiente sintaxis:

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.

Implementando código para ocultar un mensaje de texto, en una imagen




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 '''





Código completo para descarga y visualización

Solamente Oculta Información.



Referencias



1 comentario:

  1. 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