Skip to content

Instantly share code, notes, and snippets.

@Xpktro
Last active August 29, 2015 14:03
Show Gist options
  • Save Xpktro/7cdbb5cdfa78713df968 to your computer and use it in GitHub Desktop.
Save Xpktro/7cdbb5cdfa78713df968 to your computer and use it in GitHub Desktop.
Cryptography snippets (commented and developed in spanish)
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
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
#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