Last active
August 29, 2015 14:03
-
-
Save Xpktro/7cdbb5cdfa78713df968 to your computer and use it in GitHub Desktop.
Cryptography snippets (commented and developed in spanish)
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
def buscar_generadores(p): | |
# Se define el grupo Zp = {1, 2, ..., p-1} | |
grupo = set([x + 1 for x in range(p-1)]) | |
# Buscar generadores implica que se busquen numeros n tal que: | |
for n in grupo: | |
resultados = [] | |
# Para cada k en [1; p-1] | |
for k in range(1, p): | |
# Se tengan todos los resultados de n ^ k mod p | |
resultados.append((n ** k) % p) | |
# Y estos, ademas de ser siempre diferentes, pertenezcan todos al grupo | |
# Zp (el código de abajo se traduce en: "Si quitándole los elementos | |
# repetidos a lo resultados conserva su tamaño original y además no | |
# existe diferencia de este grupo con Zp, el número n es un | |
# generador") | |
if len(set(resultados)) == len(resultados) and \ | |
not grupo.difference(resultados): | |
print '%s es generador de Z%s' % (n, p,) | |
buscar_generadores(29) | |
# 2 es generador de Z29 | |
# 3 es generador de Z29 | |
# 8 es generador de Z29 | |
# 10 es generador de Z29 | |
# 11 es generador de Z29 | |
# 14 es generador de Z29 | |
# 15 es generador de Z29 | |
# 18 es generador de Z29 | |
# 19 es generador de Z29 | |
# 21 es generador de Z29 | |
# 26 es generador de Z29 | |
# 27 es generador de Z29 |
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
def generar_primos(cantidad): | |
# El set de salida es volátil por culpa de este set (no ordenado), pero | |
# genera números primos aceptables para procesos no tan exigentes. | |
numeros = set(range(cantidad, 1, -1)) | |
primos = [] | |
while numeros: | |
p = numeros.pop() | |
primos.append(p) | |
numeros.difference_update(set(range(p*2, cantidad+1, p))) | |
return primos |
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
#coding:utf-8 | |
from itertools import product | |
from re import findall | |
import string | |
def desplazar(letra, cantidad=3, alfabeto=string.lowercase): | |
return alfabeto[(alfabeto.index(letra) + cantidad) % len(alfabeto)] \ | |
if letra != u' ' else u' ' | |
def cesar(texto, cantidad=3, alfabeto=string.lowercase): | |
return u''.join(( | |
desplazar(letra, cantidad, alfabeto) for letra in texto | |
)) | |
def atbash(texto, alfabeto=string.lowercase): | |
tamano_alfabeto = len(alfabeto) | |
if tamano_alfabeto % 2 != 0: | |
alfabeto = alfabeto[:tamano_alfabeto/2] + '*' \ | |
+ alfabeto[tamano_alfabeto/2:] | |
return ''.join(( | |
list(reversed(alfabeto))[alfabeto.index(letra)] | |
if letra != ' ' else ' ' for letra in texto | |
)) | |
def polybios(texto, alfabeto=string.lowercase, desencriptar=False): | |
matriz = [ | |
['a', 'b', 'c', 'd', 'e'], | |
['f', 'g', 'h', 'ij', 'k'], | |
['l', 'm', u'nñ', 'o', 'p'], | |
['q', 'r', 's', 't', 'u'], | |
['v', 'w', 'x', 'y', 'z'] | |
] | |
resultado = '' | |
if desencriptar: | |
letras = [] | |
while texto: | |
if ' ' in texto[:2]: | |
texto = ' ' + texto | |
letras.append(texto[:2]) | |
texto = texto[2:] | |
for par in letras: | |
if ' ' in par: | |
resultado += ' ' | |
else: | |
resultado += \ | |
matriz[alfabeto.index(par[0])][alfabeto.index(par[1])][0] | |
else: | |
for letra in texto.lower(): | |
if letra == ' ': | |
resultado += ' ' | |
else: | |
for i in range(len(matriz)): | |
for l in range(len(matriz[i])): | |
if letra in matriz[i][l]: | |
resultado += '%s%s' % (alfabeto[i], alfabeto[l]) | |
return resultado | |
def vignere(texto, clave, alfabeto=string.lowercase, desencriptar=False): | |
matriz = [alfabeto[i:] + alfabeto[:i] for i in range(len(alfabeto))] | |
for i in range(len(alfabeto)): | |
matriz.append(alfabeto[i:] + alfabeto[:i]) | |
resultado = '' | |
espacios = 0 | |
for i in range(len(texto)): | |
if texto[i] == ' ': | |
resultado += ' ' | |
espacios += 1 | |
else: | |
letrafila = clave[(i-espacios) % len(clave)] | |
fila = alfabeto.index(letrafila) | |
columna = alfabeto.index(texto[i]) | |
resultado += matriz[fila][columna] | |
return resultado | |
def vigenere_new(texto, clave, alfabeto=string.ascii_lowercase, desencriptar=False): | |
resultado = '' | |
espacios = 0 | |
sentido = 1 | |
if desencriptar: | |
sentido = -1 | |
for i in range(len(texto)): | |
if texto[i] == ' ': | |
espacios += 1 | |
letra = texto[i] | |
desplazamiento = alfabeto.index(clave[(i-espacios) % len(clave)]) | |
resultado += desplazar(letra, desplazamiento * sentido, alfabeto) | |
return resultado | |
def playfair(texto, clave, desencriptar=False): | |
def unicos(texto_): | |
letras = {} | |
return [letras.setdefault(x, x) for x in texto_ if x not in letras] | |
def separar(texto_, n): | |
return [texto_[pos:pos+n] for pos in xrange(0, len(texto_), n)] | |
def normalizar(texto_): | |
# return texto_.replace(' ', '').replace('j', 'i') | |
return texto_.replace(' ', '') | |
alfabeto = 'abcdefghijklmnopqrstuvxyz' | |
# matriz = separar(unicos(normalizar(clave + string.lowercase)), 5) | |
matriz = separar(unicos(normalizar(clave + alfabeto)), 5) | |
print matriz | |
# Se pre-generan todas las combinaciones posibles para encriptar | |
encriptacion_pregenerada = {} | |
# Pares en la misma fila. | |
for fila in matriz: | |
for i, j in product(xrange(5), repeat=2): | |
if i != j: | |
encriptacion_pregenerada[fila[i] + fila[j]] = \ | |
fila[(i + 1) % 5] + fila[(j + 1) % 5] | |
# Pares en la misma columna. | |
for columna in zip(*matriz): | |
for i, j in product(xrange(5), repeat=2): | |
if i != j: | |
encriptacion_pregenerada[columna[i] + columna[j]] = \ | |
columna[(i + 1) % 5] + columna[(j + 1) % 5] | |
# Pares Cruzados. | |
for i1, j1, i2, j2 in product(xrange(5), repeat=4): | |
if i1 != i2 and j1 != j2: | |
encriptacion_pregenerada[matriz[i1][j1] + matriz[i2][j2]] = \ | |
matriz[i1][j2] + matriz[i2][j1] | |
# Se generan las combinaciones para desencriptar. | |
desencriptar_pregenerada = \ | |
dict((v, k) for k, v in encriptacion_pregenerada.iteritems()) | |
if desencriptar: | |
return ' '.join(desencriptar_pregenerada[p] | |
for p in separar(normalizar(texto), 2)) | |
else: | |
norepetidos = findall(r'(.)(?:(?!\1)(.))?', normalizar(texto)) | |
return ' '.join(encriptacion_pregenerada[a + (b if b else 'x')] | |
for a, b in norepetidos) | |
print vigenere_new('wyoodipwopt'[::-1], 'pelo', desencriptar=True) | |
print playfair('rflig dxhdj yeefa dtgfn yeqkr ojqcf anmjy mecqe urbyu ebnme frjyb rrbqzqkube c', 'numaboa', desencriptar=True) | |
# print cesar(u'el dia de mañana deben enviar armamento y municiones', alfabeto=u'abcdefghijklmnñopqrstuvwxyz') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment