Un script python de esteganografía
Con este simple script fue con el que oculte la imagen en la entrada anterior. (simplemente le cambio la paridad al ultimo parametro del color RGB.) Este script es solo para tener una idea de lo que es la esteganografía y para mostrar una simple implementacion. Espero que les guste.
#!/usr/bin/env python # Archivo: fusion.py import Image import sys def fusionar(arch1,arch2): try: imagen =Image.open(arch1) msg =Image.open(arch2) xsize,ysize = imagen.size xsizeMsg,ysizeMsg = msg.size if (xsizeMsg,ysizeMsg) != (xsize,ysize): return -1 # imagenes de distinta dimencion for y in range(ysize): for x in range(xsize): pixelImg = imagen.getpixel((x,y)) pixelMsg = msg.getpixel((x,y)) promRGB = (pixelMsg[0]+pixelMsg[0]+pixelMsg[0])/3 if promRGB > 125 : if pixelImg[2]%2!=0: pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]+1) if (pixelImg[2] == 255) : pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]-1) imagen.putpixel((x,y),pixelSet) else: if pixelImg[2]%2==0: pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]+1) imagen.putpixel((x,y),pixelSet) imagen.save("fus.bmp") return 0 except: return -1 def desFusionar(arch1): try: imagen =Image.open(arch1) xsize,ysize = imagen.size for x in range(xsize): for y in range(ysize): pixelImg = imagen.getpixel((x,y)) if pixelImg[2] % 2 ==0: imagen.putpixel((x,y),(255,255,255)) else: imagen.putpixel((x,y),(0,0,0)) imagen.save("des.bmp") return 0 except: return -1 def imprimirModoDeEjecucion(): print "BinSD v1.0" print "Mode de ejecucion:" print " fusion.py -D arch1" print " fusion.py -C arch1 arch2" if len(sys.argv) == 3 and sys.argv[1]== "-D": print "Procesando...", if desFusionar(sys.argv[2])==0: print "ok" else: print "err" elif len(sys.argv) == 4 and sys.argv[1]== "-C": print "Procesando...", if fusionar(sys.argv[2],sys.argv[3]) == 0: print "ok" else: print "err" else: imprimirModoDeEjecucion()
En esta entrada quiero felicitar a Arnau y a Alejandro J. Cura. que lograron sacar el desafio.
el script con el que logro sacar el codigo Arnau es …
import PIL.Image img = PIL.Image.open(”fus.bmp”) img.point([0]*256+[0]*256+[( (x&1) << 8 ) for x in range(256)]).show()
el script con el que lo saco Alejandro es …
from itertools import izip, chain, repeat from PIL import Image def grouper(n, iterable, padvalue=None): return izip(*[chain(iterable, repeat(padvalue, n-1))]*n) i=Image.open("fus.bmp") r,g,b=i.split() i=b s=i.tostring() d = ["%d"%(ord(c)&1) for c in s] o = [] for g in grouper(8, d): b = "".join(g) o.append(chr(int(b,2))) b="".join(o) d=Image.fromstring("1",(800,480),b) d.show()
😉
en 28 octubre 2008 en 18:46
Mi script para descifrarlo fue:
from itertools import izip, chain, repeat
from PIL import Image
def grouper(n, iterable, padvalue=None):
return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)
i=Image.open("fus.bmp")
r,g,b=i.split()
i=b
s=i.tostring()
d = ["%d"%(ord(c)&1) for c in s]
o = []
for g in grouper(8, d):
b = "".join(g)
o.append(chr(int(b,2)))
b="".join(o)
d=Image.fromstring("1",(800,480),b)
d.show()
saludos,
—
alecu
en 28 octubre 2008 en 18:47
por supuesto que tu blog destruyó el formato del script anterior.
Algunos blogs te dejan hacer un «preview» antes de publicar los comments. sigh.
—
alecu
en 29 octubre 2008 en 9:00
Cuando te dije que sólo había que revisar los bits menos significativos de cada componente, me dijiste que no habías hecho nada a nivel de bit.
La verdad es que me dejaste sin saber por donde acometer el desafío.
Pues:
if promRGB > 125 :
if pixelImg[2]%2!=0:
pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]+1)
if (pixelImg[2] == 255) :
pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]-1)
imagen.putpixel((x,y),pixelSet)
else:
if pixelImg[2]%2==0:
pixelSet = (pixelImg[0],pixelImg[1],pixelImg[2]+1)
imagen.putpixel((x,y),pixelSet)
es igual que:
bit= 1 if promRGB > 125 else 0
pixelset=(pixelImg[0],pixelImg[1],pixelImg[2]&254|bit)
imagen.putpixel((x,y),pixelSet)
Qué quieres que te diga, «los bits esos grandes desconocidos que lo han hecho todo posible».
en 29 octubre 2008 en 9:12
Tengo unos minutos libres, así que voy a explicarlo un poco.
el bit menos significativo, que es el que aporta menos valor, aporta exactamente 2^0 (o pytonísicamente escribiendo 2**0) es decir 1
Todos los números impares tendrán por primer bit 1, mientras que todos los números impares tendrán por primer bit 0.
Por eso a%2 es igual que a&1.
Doy por supuesto que todos sabemos lógica boleana, pero pa repasar:
1&1 = 1
1&0 = 0
0&0 = 0
1|1 = 1
1|0 = 1
0|0 = 0
por eso si queremos machacar el último bit, lo mejor es asegurarnos de ponerlo a 0 primero
haciéndole un AND con 11111110 es decir 254
luego le hacemos un OR con el bit que queremos escribir y listo
Venga, tengo ganas de un próximo desafío.
en 17 abril 2010 en 16:47
el ejemplo esta excelente….
mi pregunta es como puedo sacar una letra de una imagen o el texto de una imagen, no se si me podrias orientar en este tema…
Gracias : )
en 19 abril 2010 en 13:44
disculpen una pregunta se puede sacar las letras de las imagens con python?
lo que pasa es que estoy tratando de sacar las letras de una imagen pero la verdad que aun no e logrado todavia….
nose si me podrian ayudar en este tema….
Gracias
en 20 abril 2010 en 18:36
por hay te sirve
ese ejemplo de RNA
en 22 abril 2010 en 1:26
grasias…
esta muy bueno el tutorial…!!
en 3 diciembre 2011 en 20:57
Another Python implementation:
http://www.vivaolinux.com.br/artigo/Esteganografia-e-Esteganalise-transmissao-e-deteccao-de-informacoes-ocultas-em-imagens-digitais
[]’s