[TPC-C] #2 Cifrado de Vigenère

Iniciado por WhiZ, Febrero 16, 2014, 12:38:48 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Febrero 16, 2014, 12:38:48 PM Ultima modificación: Febrero 16, 2014, 01:15:36 PM por 11Sep
The Python Challenges
Nº 2 Cifrado de Vigenére
Criptografía



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 salida debe ser en minúsculas.
  • Se deben respetar los caracteres no alfabéticos.
  • No se tiene en cuenta la letra ñ.


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 (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta)  y a No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

Los criterios de evaluación son los mismos establecidos en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

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:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
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.


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

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!







No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

ahora lo entiendo todo xd ya envíe mi code!

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

# 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

>>> 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: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Saludos!
WhiZ


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
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


Hoy codeo algo y mando por simple idea de practicar y juegar :P

Regards,
Snifer
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


Llaman traidor a la persona que evito que caiga el foro, gente bruta!



Febrero 18, 2014, 07:48:40 PM #7 Ultima modificación: Febrero 18, 2014, 07:56:52 PM por WhiZ
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


HOLA!!!

Codigo enviado.

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


GRACIAS POR LEER!!!
"Algunos creen que soy un bot, puede que tengan razon"
"Como no se puede igualar a Dios, ya he decidido que hacer, ¡SUPERARLO!"
"La peor de las ignorancias es no saber corregirlas"

*Shadow Scouts Team*                                                No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Febrero 24, 2014, 02:20:59 PM #9 Ultima modificación: Febrero 24, 2014, 07:44:24 PM por 11Sep
Resultados:

Los códigos se evaluaron usando los siguientes parametos:

Mensaje: Retos python Underc0de.
Clave: undercode

Resultado: lrwsj rmwlia xrugff0hy.

11Sep

Código: python
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
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
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
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!







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, 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.
Sigueme en Twitter : @Sankosk
Estos nuevos staff no tienen puta idea XD

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.







No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

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

HOLA!!!

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

GRACIAS POR LEER!!!
"Algunos creen que soy un bot, puede que tengan razon"
"Como no se puede igualar a Dios, ya he decidido que hacer, ¡SUPERARLO!"
"La peor de las ignorancias es no saber corregirlas"

*Shadow Scouts Team*                                                No tienes permitido ver los links. Registrarse o Entrar a mi cuenta