Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- # Written by kenkeiras
- ##############################################################################
- # Copyright (C) 2011 kenkeiras
- #
- # This program is free software. It comes without any warranty, to
- # the extent permitted by applicable law. You can redistribute it
- # and/or modify it under the terms of the Do What The Fuck You Want
- # To Public License, Version 2, as published by Sam Hocevar.
- #
- # See http://sam.zoy.org/wtfpl/COPYING for more details.
- ##############################################################################
- # Cifrado usando Game 3-4
- import sys,time
- if len(sys.argv) in [2,3]:
- print sys.argv[0]," [<key> <input> <output>]"
- exit(0)
- dibujos = len(sys.argv) > 4
- # Genera un campo
- def genf(h,w,val=False):
- f=[]
- for i in xrange(h):
- r=[]
- for j in xrange(w):
- r.append(val)
- f.append(r)
- return f
- # Mantiene n entre 0 y d
- def rmd(n,d):
- if n < 0:
- n = d + n
- return n % d
- # Dibuja las figuras iniciales
- #
- # #
- # #
- # #### #
- # # ####
- # #
- # #
- #
- def drawpair(f, xo, yo):
- # First one
- f[yo][xo+2]=True
- f[yo+1][xo+2]=True
- f[yo+2][xo+2]=True
- f[yo+3][xo+2]=True
- f[yo+2][xo]=True
- f[yo+2][xo+1]=True
- f[yo+2][xo+2]=True
- f[yo+2][xo+3]=True
- # Second one
- f[yo+2][xo+5]=True
- f[yo+3][xo+5]=True
- f[yo+4][xo+5]=True
- f[yo+5][xo+5]=True
- f[yo+4][xo+4]=True
- f[yo+4][xo+5]=True
- f[yo+4][xo+6]=True
- f[yo+4][xo+7]=True
- return f
- # Hace XOR de la posición [i][j] del campo con un bit
- def bitFlip(f, i, j,b,n):
- f[i][j] = f[i][j] ^ (b & (1<<n) > 0)
- return f
- # "Introduce" la clave [k] en el campo [f]
- def addkey(f, k ):
- # Comprueba que la clave cabe en el campo
- if (len(f) * len(f[0]))/8 < len(k):
- print "Campo demasiado corto"
- exit(1)
- i = 0
- j = 0
- # Para cada celda
- for b in k:
- for n in xrange(8):
- # Hace XOR de la celda y el bit
- # de la clave correspondiente
- f=bitFlip(f,i,j,ord(b),n)
- j+=1
- if j >= len(f[i]):
- j = 0
- i+=1
- return f
- # Hace que el campo pase al siguiente estado
- def nextstep(f):
- # Genera un nuevo campo
- o = genf(len(f),len(f[0]))
- # Por cada celda
- for y in xrange(len(f)):
- for x in xrange(len(f[y])):
- # Se comprueba el número de vecinos
- c = 0
- for i in [-1,0,1]:
- for j in [-1,0,1]:
- # Sin contarse a uno mismo!
- if [i,j] == [0,0]:
- continue
- if (f[rmd( y+i, len(f) )] [rmd( x+j, len(f[0]) )]):
- c+=1
- # Activar si el número es 3 o 4
- o[y][x]=c in [3,4]
- return o
- # Muestra el campo
- def fp(f):
- print "+"+"-"*len(f[0])+"+"
- # Por cada celda
- for r in f:
- sys.stdout.write("|")
- for d in r:
- # '0' si está encendida y ' ' en otro caso
- x='O' if d else ' '
- sys.stdout.write(x)
- sys.stdout.write("|\n")
- print "+"+"-"*len(f[0])+"+"
- # Convierte un campo en una cadena de Bytes
- def getBytes(f):
- s = ""
- i = 0
- act = 0
- # Para cada celda
- for r in f:
- for c in r:
- # Añadimos el bit
- act |= (c*(1<<i))
- i+=1
- # Si rellenamos un byte, lo añadimos a la cadena
- # y vuelta a empezar
- if ( i > 7 ):
- s+=chr(act)
- act=0
- i=0
- return s
- h=25 # Anchura
- w=30 # Altura
- # Generamos un campo
- f=genf(h,w)
- # Dibujamos las figuras ( con un offset 1,1 por ejemplo )
- f=drawpair(f,1,1)
- # Esperamos 200 generaciones
- for i in xrange(200):
- print i
- if dibujos:
- fp(f)
- f=nextstep(f)
- # Mostramos el campo
- if dibujos:
- fp(f)
- # Leemos la clave
- if (len(sys.argv)>3):
- k=sys.argv[1]
- else:
- k = raw_input("Clave:")
- # La codificamos en el autómata
- addkey(f,k)
- fp(f)
- # Le damos 75 generaciones para que se mezcle bien
- for j in xrange(75):
- i+=1
- print i
- if dibujos:
- fp(f)
- f=nextstep(f)
- # Leemos los nombres de los archivos
- fin = ""
- if (len(sys.argv)>3):
- fin = sys.argv[2]
- else:
- fin = raw_input("Archivo a cifrar/descifrar:")
- fon = ""
- if (len(sys.argv)>3):
- fon = sys.argv[3]
- else:
- fon = raw_input("Archivo de salida:")
- # Los abrimos
- fi = open(fin,"rb")
- fo = open(fon,"wb")
- # Comprobamos el número de bytes que podemos recibir por cada estado
- avail = (len(f) * len(f[0]))/8
- # Y [des]ciframos
- while True:
- if dibujos:
- fp(f)
- c = fi.read(avail) # Leemos los bytes originales
- # Si ya acabamos, cerramos
- if len(c) < 1:
- break
- bt = getBytes(f) # Leemos los del autómata
- # Guardamos la mezcla
- for i in xrange(len(c)):
- fo.write(chr(ord(c[i])^ord(bt[i])))
- # Y pasamos a la siguiente generacion
- f=nextstep(f)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement