Underc0de

Programación Scripting => Python => Mensaje iniciado por: WhiZ en Febrero 16, 2014, 12:38:48 PM

Título: [TPC-C] #2 Cifrado de Vigenère
Publicado por: WhiZ en Febrero 16, 2014, 12:38:48 PM
The Python Challenges
Nº 2 Cifrado de Vigenére
Criptografía

(http://sia1.subirimagenes.net/img/2014/02/16/140216044358182224.png)

Objetivo:


Programar las funciones necesarias que permitan codificar y decodificar un mensaje usando el Cifrado de Vigenére, teniendo en cuenta los siguientes aspectos:



La fecha máxima de entrega es para el Domingo 23 de Febrero. Los códigos deben ser enviados por mp al moderador de la sección (11Sep (http://underc0de.org/foro/profile/11Sep))  y a WhiZ (http://underc0de.org/foro/profile/WhiZ/).

Los criterios de evaluación son los mismos establecidos en este post (http://underc0de.org/foro/python/the-python-challenges/).

Sólo se tendrá en cuenta el último código recibido hasta el 23 de Febrero. Los códigos no deben ser publicados bajo ninguna circunstancia; de lo contrario, el usuario será descalificado del reto, sin excepción.


Enlaces de ayuda:

Cifrado de Vigenère [es] (http://es.wikipedia.org/wiki/Cifrado_de_Vigen%C3%A8re)
Función ord() [en] (http://docs.python.org/2/library/functions.html#ord)
Función chr() [en] (http://docs.python.org/2/library/functions.html#chr)
Método lower() [en] (http://docs.python.org/2/library/stdtypes.html#str.lower)
itertools.cycle() [en] (http://docs.python.org/2/library/itertools.html#itertools.cycle)


Nota: Todas las dudas acerca del reto, deberán realizarse en este mismo hilo.
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: deni_celine en Febrero 17, 2014, 04:01:29 PM
Holaaaa , tengo una duda respecto a este reto, o mejor dicho respecto a los criterios de evaluación :3
uno de los puntos dice : "Número de librerías utilizadas: será mejor la calificación mientras menos librerías se requieran para cumplir el o los objetivos."
Pero en enlaces de ayuda hacen mensión a Itertools , que es mejor evaluado, hacer uso de la libreria o no hacerlo ?

Saludos :P
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: Once en Febrero 17, 2014, 05:36:32 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Holaaaa , tengo una duda respecto a este reto, o mejor dicho respecto a los criterios de evaluación :3
uno de los puntos dice : "Número de librerías utilizadas: será mejor la calificación mientras menos librerías se requieran para cumplir el o los objetivos."
Pero en enlaces de ayuda hacen mensión a Itertools , que es mejor evaluado, hacer uso de la libreria o no hacerlo ?

Saludos :P

Aprovechando tu pregunta e intentando responder a un mp que merecibí preguntando algo similar, intentaré explicar como evaluamos los codes.

La calificación es así:

Se separan los códigos que cumplen las condiciones y lo que no las cumplen.

Si más de un código cumple todas las condiciones se evalua la velocidad de ejecución de los scripts. Si empatan o los tiempos de ejecución.

Si los tiempos de ejecución son muy cercanos, se declara empate y pasamos a evaluar los criterios que mencionamos en el prime post.

Con respecto a tu pregunta, tienes que pensar si vale la pena codear toda un función entera y depronto sacrificar algo de tiempo (a veces puedes codear funciones más rápidas) o simplemente usar una libreria.

Lo que no calificamos es la longitud del código, así los participantes son libres de tener en cuenta todos los aspectos y no se tienen que preocupar por hacer "maromas" para tener el código más corto (para eso tenemos los retos relámpago).

En los retos relámpago, la única regla es que se cumplan TODOS los requisitos que se piden para cada reto en especial. (No se tiene en cuenta la evaluación de arriba).

Saludos!
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: deni_celine en Febrero 17, 2014, 05:57:24 PM
ahora lo entiendo todo xd ya envíe mi code!
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: WhiZ en Febrero 17, 2014, 09:48:18 PM
Quería comentarles que existe la posibilidad de evitar el uso de librerías externas por medio de yield.

Para aquellos que no conocen este statement, les explico un poco en qué consiste y cómo se utiliza. Con ello espero que deduzcan porqué adquiere importancia en este reto.

En términos generales (muy generales :P) podemos decir que yield es similar a return. El tema es que, a diferencia de return, al utilizar yield dentro de un bucle (y de una función/método, por supuesto) el proceso de iteración no es interrumpido, lo que nos permite obtener más de un valor del bucle. Es decir, un bucle con return nos devuelve un único valor e interrumpe la iteración, mientras que yield nos permite devolver más de un valor debido a que no interrumpe la iteración.

Algunos se estarán preguntando de qué forma se devuelven los valores retornados por yield. Bueno, aquí existe otra diferencia con return. Mientras que return nos permite realizar lo que conocemos como asignación (almacenamiento de un valor en una variable), yield nos crea un objeto de tipo "generator". Estos objetos presentan un método llamado "next()" que nos devuelve uno por uno los valores que el objeto ha almacenado.

Veamos un ejemplo para entenderlo mejor. Primero crearemos 2 funciones (serán similares, salvo por el hecho que en la segunda reemplazaremos el return por el yield) y luego veremos qué sucede al utilizarlas.

Código (python) [Seleccionar]

# Función con return
def funcReturn(i):
    while i < 10:
        if i%2 == 0:
            return i
        i += 1
    print "Hemos llegado hasta", i

# Función con yield
def funcYield(i):
    while i < 10:
        if i%2 == 0:
            yield i
        i += 1
    print "Hemos llegado hasta", i


Ahora veamos que sucede al utilizarlas:

Código (python) [Seleccionar]

>>> r = funcReturn(0)    # Asignamos a la variable "r" el valor devuelto por funcReturn()
>>> y = funcYield(0)    # Creamos un objeto "y" que almacenará los valores devueltos por funcYield()
>>> type(r)    # Verificamos la asignación
<type 'int'>
>>> type(y)    # Verificamos la creación del objeto tipo "generator"
<type 'generator'>
>>>

# Como "r" es una variable de tipo "int", podemos ver su valor con un simple print
>>> print r
0
>>>

# Como "y" es un objeto, print no nos sirve para ver los valores que ha almacenado
>>> print y
<generator object funcYield at 0xb5f71f2c>
>>>

# Para ver los valores contenidos por "y", deberemos utilizar su método next()
>>> while True:
try:
print y.next()
except StopIteration:
break


0
2
4
6
8
Hemos llegado hasta 10
>>>


Bueno, espero haber sido claro y, lo que es más importante, que les sea de utilidad.

A continuación les dejo un link para que los interesados leer un poco más: yield (http://docs.python.org/2/reference/simple_stmts.html#yield)

Saludos!
WhiZ
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: WhiZ en Febrero 17, 2014, 10:25:29 PM
Ahora algunas generalidades del cifrado de Vigenère. Como algunos habrán leído por ahí, este cifrado corresponde (al igual que el cifrado César) a los de tipo simétrico, es decir que utiliza la misma clave tanto para cifrar como para descifrar. La diferencia radica en el tipo de clave y la forma en que esta se aplica sobre el mensaje a cifrar/descifrar.

Código (text) [Seleccionar]
Cifrado César:
--------------
   - Clave numérica.

   - A cada carácter del mensaje a cifrar/descifrar se le suma/resta el valor numérico de la clave (cifrado por desplazamiento).

Ejemplo (basado en ascii):
    clave = 4
    mensaje = "abcd"
    cifrado = "efgh"
   
    a (97) + 4 = e (101)
    b (98) + 4 = f (102)
    c (99) + 4 = g (103)
    d (100) + 4 = h( 104)

Cifrado de Vigenère:
--------------------
    - Clave alfanumérica.

    - A cada carácter del mensaje a cifrar/descifrar se le suma el valor numérico correspondiente a un carácter de la palabra clave. Al carácter siguiente del mensaje se le suma el valor correspondiente al siguiente carácter de la palabra clave. En caso de que el mensaje sea más largo que la palabra clave, esta última será reutilizada las veces que sea necesario, hasta codificar el mensaje por completo.

Ejemplo (basado en ascii):
    clave = "reto"
    mensaje = "abcd"
    cifrado = "kyok"

    a (97) + r (114) = 211 --> k (107)
    b (98) + e (101) = 199 --> y (121)
    c (99) + t (116) = 215 --> o (111)
    d (100) + o (111) = 211 --> k (107)

En este ejemplo, la longitud de la clave coincide con la del mensaje. Si el mensaje fuera más largo, luego de utilizar el último carácter de la clave, continuaremos con el primero.


Espero que les sirva!

Saludos!
WhiZ
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: Snifer en Febrero 18, 2014, 04:27:58 PM
Hoy codeo algo y mando por simple idea de practicar y juegar :P

Regards,
Snifer
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: WhiZ en Febrero 18, 2014, 07:48:40 PM
Excelente! Todo código será bienvenido, por supuesto! Esto lo digo también para aquellos que no han llegado a la inscripción pero que quieran "participar".

Para la próxima , directamente publicaremos el reto y la fecha límite de entrega, sin inscripción previa, de manera tal que aquellos que todos puedan participar.

Saludos!
WhiZ
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: 79137913 en Febrero 20, 2014, 11:43:05 AM
HOLA!!!

Codigo enviado.

Código (python) [Seleccionar]
for x in-2,2:print" 3 1 9R7u3l1e9z7"[::x]

GRACIAS POR LEER!!!
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: Once en Febrero 24, 2014, 02:20:59 PM
Resultados:

Los códigos se evaluaron usando los siguientes parametos:

Mensaje: Retos python Underc0de.
Clave: undercode

Resultado: lrwsj rmwlia xrugff0hy.

11Sep

Código (python) [Seleccionar]
def iter_key(s):
    i = 0
    while True:
        yield s[i % len(s)]
        i += 1
   
def vigenere(key, msg, cipher=1):
    key = iter_key(key.lower())
    msg = msg.lower()
   
    buffer = ""
   
    if cipher:
        for byte in msg:
            if "a" < byte < "z":
                buffer += chr((((ord(byte) - 97) + (ord(key.next()) - 97)) % 26) + 97)
            else:
                buffer += byte
    else:
        for byte in msg:
            if "a" < byte < "z":
                buffer += chr((((ord(byte) - 97) - (ord(key.next()) - 97)) % 26) + 97)
            else:
                buffer += byte

    return buffer


print vigenere("undercode", "Retos python Underc0de.", cipher=True)


Salida: lrwsj rmwlia xrugff0hy.

No cumplen las condiciones:

Sanko

Código (python) [Seleccionar]
def vigenere(s, k, z=True):
        tchr,tord = chr,ord

        if z:
                print [tchr((tord(x[0]) + tord(x[1])) % 256) for x in zip(s, k)]
        else:
                print [tchr((tord(x[0]) - tord(x[1])) % 256) for x in zip(s, k)]


Salida: ['\xc7', '\xd3', '\xd8', '\xd4', '\xe5', '\x83', '\xdf', '\xdd', '\xd9']

deni_celine

Código (python) [Seleccionar]
class Vigenere:
    '''Clase que permite codificar y decodificar msj haciendo uso del  Cifrado vigenEre '''
   
    def __init__(self,valor="undercode"):
        '''Inicializa la clase y la clave'''
        self.k=valor
   
    def codificar(self,msj):
        '''Retorna el mensaje cifrado'''
        key=''.join([self.k[i%len(self.k)]for i in range(len(msj))])
        return ''.join([chr(97+(ord(msj[i])+ord(key[i])-194)%26)if(123>ord(msj[i])>96)else msj[i]for i in range(len(msj))])
   
   
    def decodificar(self,msj):
        '''Retorna el mensaje decodificado'''
        key=''.join([self.k[i%len(self.k)]for i in range(len(msj))])
        return ''.join([chr(97+(ord(msj[i])-ord(key[i])+26)%26)if(123>ord(msj[i])>96)else msj[i]for i in range(len(msj))])
   
# fin clase

#ejemplo de uso
vigenere = Vigenere("undercode")

msj = "Retos python Underc0de."
codificado = vigenere.codificar(msj)
print "Msj codificado :", codificado
print "Msj decodifica :",vigenere.decodificar(codificado)


Salida: Rrwsj dbxbbq Uprhvw0gi.

79137913

Código (python) [Seleccionar]
def vigenere(a, b):
    d = []
    h = 0
    g = ""
    for c in b.lower():
        d.append(ord(c)-97)
    e = len(d)
    for c in a.lower():
        f = ord(c)
        if f < 97 or f > 122:
            g = g + c
        else:
            f = f + d[h]
            h = h + 1
            if h == e:
                h = 0
            if f > 122:
                f = f - 26
            g = g + chr(f)
    return g


Salida: lrwsj rmwlia xrugff0hy.
Nota: Cifra correctamente el mensaje, pero no lo descifra


Ganador:
Sin ganadores.


Saludos!
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: Sanko en Febrero 24, 2014, 07:05:45 PM
CitarSe deben respetar los caracteres no alfabéticos.
No se supone que el algoritmo debía tener en cuenta cualquier tipo de resultado? es decir, si se contempla el uso de carácteres no-alfabéticos todo el resultado cambia, pero la implementación del algoritmo sigue siendo válida, no porque no obtengan una misma salida quiere decir que el cifrado en sí este mal.

En mi opinión mi única sugerencia hacia los retos que se proponen es que sean más claros a la hora de publicarlos y que a ser posible cuando se envien los scripts junto con alguna duda, esta pueda ser respondida...

Saludos.
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: Once en Febrero 24, 2014, 08:30:56 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
CitarSe deben respetar los caracteres no alfabéticos.
No se supone que el algoritmo debía tener en cuenta cualquier tipo de resultado? es decir, si se contempla el uso de carácteres no-alfabéticos todo el resultado cambia

Se suponía que se deben respetar los caracteres no alfabéticos y no se tiene en cuenta la letra ñ lo que significa que si hay un caracter que no es alfabético ese caracter simplemente no se cifra.

La única forma que el resultado cambie es si se cambian las letras del alfabeto de posición o si se agrega la ñ

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
pero la implementación del algoritmo sigue siendo válida, no porque no obtengan una misma salida quiere decir que el cifrado en sí este mal.

El hecho que hagas un par de sumas y un módulo no significa que la implementación está bien. Lee de nuevo como funciona el cifrado Vigenere y verás que tu código no es un Vigenere.

Y sí, si las salidas no son las mismas cuando cuando la clave y el mensaje son los mismos, significa que el cifrado está mal.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
En mi opinión mi única sugerencia hacia los retos que se proponen es que sean más claros a la hora de publicarlos

Eso es un hecho, para los próximos retos intentaremos ser lo más claros posibles.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
y que a ser posible cuando se envien los scripts junto con alguna duda, esta pueda ser respondida...

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Nota: Todas las dudas acerca del reto, deberán realizarse en este mismo hilo.
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: deni_celine en Febrero 24, 2014, 09:20:11 PM
q mal q nadie gano :c , para la otra! el code publicado tampoco descifra bien y no esta contemplando la "a" ni la "z" , dijo el picado xD
Título: Re:[TPC-C] #2 Cifrado de Vigenère
Publicado por: 79137913 en Febrero 25, 2014, 01:39:37 AM
HOLA!!!

Que lastima, no lei bien la consigna, no hubiese sido problema que descifrara...

GRACIAS POR LEER!!!