Soluciones Desafío 105

Pardillano dice:

Con este desafío cierro una serie de propuestas relacionadas con temas informáticos. El D100 “Torneos escolares”, pretendía aplicar algoritmos de ordenación. En el D103, “el Artipalo Vietnamita”, se encontraba camuflado el problema de las torres de Hanoi, un clásico en los cursos de programación. Y este D105, “la torre de Babel”, se mete de lleno en criptografía. De los tres, este es el que me ha resultado al final más complicado, a pesar de que su preparación fue más sencilla. Quise atajar un tema complicado simplificando el planteamiento, y aplicando un protocolo moderno a un método de cifrado antiguo, Vigenère. Para que funcionara vosotros teníais que razonar en un sentido determinado, y al no resultar así, no he sabido redirigir el desafío.

Para dar respuesta a este cambio de planes, me he metido en un follón de programación de tres pares de narices, lo que me ha llevado a descuidar mi papel como desafiante. Visto ahora, y dada la dinámica con que fue planteado, con mensajes secretos a través del blog, entiendo que ha podido resultar un poco desesperante leer tanto mensaje cifrado y no saber que se estaba tramando, o ni siquiera tener claro exactamente lo que hay que hacer. Esto aderezado con fases nuevas improvisadas, sin lugar para intervenir, anunciadas pronto y disponibles tarde, … Menos mal que Super ha echado una mano en lo que ha podido y más, tanto al resto de desafiados (con pistas, ROT13, conversaciones, ejemplos) como a mi (con sus consejos, pruebas, la demostración final).

Espero que me disculpéis por estos fallos. En el lado positivo, yo me he divertido mucho, he disfrutado programando la web, y he visto todo lo que se puede aprender de Super (y lo que queda, cuando cuente sus secretos). También estoy intrigadísimo con el trabajo de Rubenman, que como no iba en la misma dirección que yo, no he llegado a comprender.

En el adjunto tenéis un resumen de lo que ha ido pasando, y una transcripción de algunos de los mensajes. Incompleta, porque vuestra participación me ha SUPERado y me he perdido en muchos detalles. Espero que los demás, en especial Rubenman y Super, la complementen en los comentarios.

D105_Imagen_Blog_SolucionEl jueves nuevo Desafío de Rubenman

D105_Pardillano

Anuncios

17 pensamientos en “Soluciones Desafío 105

  1. El desafío muy bueno, me incorporé tarde por razones estivales y andaba algo despistado. Por ese motivo utilicé la clave “SmnSntDPsn”, sin vocales que reflejaba mi primera impresión.
    Extraer esta clave era muy sencillo del último texto enviado a Pardillano, simplemente al introducir la clave de él ligeramente corrida “nesContraGatoRato”, para que pueda haber concordancia de módulos, nos ofrecía una duplicación de letras en la zona central que eran la clave, se puede comprobar.
    No obstante introduje pronto unos monosílabos por si alguien quería también intetar la otra vía.
    Yo la he utilizado con algunos de vosotros y funciona, sólo hay que tener presente la concordancia de módulos de clave y letras para que funcione mejor.
    Evidentemente yo pensaba que Pardillano ya la tendría en mi primer mensaje, simplemente quería añadir una piedrecita al resto. Eso prueba mi total despiste inicial
    Desde un principio pensé que había que intentar sacar las claves tras la lectura de un primer mensaje, sólo me pareció posible si se cumplen unas circunstancias y aun así es pesado salvo un apoyo informático. De hecho con Super ni lo intenté porque las coincidencias de letras no me ayudaban mucho, aunque sí tengo la sospecha de que hay repetidas parejas de fonemas en su clave y aparte me imaginé que eludiría utilizar monosílabos.
    En cuanto a la Fase 3, tenía dos opciones y elegí para Super la que menos le gustó, pero no entiendo por qué no le servía. Yo le mando un mensaje que nada tiene que ver con el mundial, la clave algo metafórico de ese evento, me envía un mensaje y yo le devuelvo su mismo mensaje encriptado en mi clave. Supuse que ya le bastaría para descifrarlo y esperaba que él me devolviera un mensaje que al introducir mi clave, yo extraería la suya.
    Y todo parece ser que era al revés, yo tenía que decriptar primero. Comprenderemos una vez más que en temas informáticos uno está muy pez y si no le indican claramente los pasos, no hacemos nada.

    • No, no era al revés. Tenía que haber pasado eso que dices:
      Tú me reenvias mi propio mensaje con tu clave, yo quito la mía y finalmente tú quitas la tuya. Si no ha pasado eso, alguno nos hemos equivocado. Habría que repasar la conversación. Si ha sido culpa mía, lo siento.
      No sólo eres tú, creo que la informática hace a veces difícil ver el bosque.

  2. No puedo quejarme porque a mí me ha ido muy bien, pero menudo desastre…
    Pardillano, un par de comentarios a lo que cuentas en tu solución:

    Si ese protocolo de tres pasos lo inventó realmente Shamir, no tenía ni idea. Yo conocía el problema desde hace tiempo, en su versión con candados (aunque el principio no reconocí el problema), y la verdad es que en esa versión no es necesario referirse para nada a la informática.

    En mi opinión (desviada, seguro), la versión que yo llamo “original” (que muy bien puede haber sido la inspiración de Shamir, si es que él no lo inventó) con candados es, por un lado, más apta para todos los públicos, y por otro, más difícil.
    Por ambos motivos, creo que hubiera sido mejor proponerlo sin hablar de informática, y es que, repito, es una opinión personal, la versión informática es demasiado fácil.

    Me explico: la idea de añadir otro candado en vez de pretender descerrajar el primero es una genialidad que a mí no se me ocurrió cuando me encontré el problema (creo que en un libro). ¿Quién ha visto una caja con dos candados? ¡Lo que queremos es abrirla!
    Pienso que requiere una inspiración que yo no tengo. Pero eso mismo lo convierte en un gran candidato a Desafío, porque no importa que todo el mundo quede perplejo, siempre se pueden ir dando pistas.

    Al meter el problema en el ámbito informático, te viste obligado a preparar unas herramientas comunes que permitieran el proceso sin preacuerdos previos de ningún tipo (primero tu Excel Vigenère, luego tu web fase 3) para que las usáramos los mortales y ejecutáramos el protocolo. Pero la misma existencia de esas herramientas limita tanto las posibilidades que la genialidad ya no es tan genial, dejando un Desafío más descafeinado que se puede atacar con simple lógica:
    Si el receptor del mensaje devuelve inmediatamente otro igual de largo, y la lista de herramientas a usar consta de dos funciones (encriptar y desencriptar), no hay que elegir entre muchas posibilidades para adivinar lo que pueda haber hecho.
    Si lo que recibe de vuelta el primero no se puede desencriptar (no tendría sentido intentarlo, la comunicación no es con el primero), las opciones de éste son también muy limitadas: o se lo reenvía desencriptado con su propia clave (no conoce otra), o se lo envía reencriptado con su propia clave. Cuando el receptor recibe finalmente el mensaje, el escenario es igual de limitado:
    O decodifica el mensaje usando una de sus dos herramientas, o no puede, dependiendo de la decisión del enviador en el paso 2.
    Tras unos pocos intentos, incluso sin comunicaciones en abierto, debería haber sido fácil encontrar la combinación de herramientas apropiada: Cod,Cod,Dec,Dec. Sobre todo teniendo en cuenta que la primera debería ser por lógica Cod y la última Dec.

    Es obvio que esta línea de pensamiento es demasiado simplista (es fácil irse por las ramas al no entender qué se pretende y empezar a enviar mensajes nuevos no relacionados en cualquier momento, estropeando el protocolo), pero creo que las pistas eran buenas para poder intuir qué pasaba. Yo empecé sin entenderlo y tus comentarios me sirvieron, pero claro, yo ya conocía el problema.

    Visto lo visto, supongo que todas estas opiniones mías son infundadas, porque la versión “fácil” ha resultado ser muy difícil.

    Pardillano, ¿que habría pasado de haberlo presentado con candados? Para tí hubiera sido más cómodo, desde luego, porque te hubiera liberado de construir las herramientas, pero, ¿habría sido mejor para los desafiados?

    Pregunta para todos: ¿vosotros qué opináis?

    P.D. Aunque no tenga nada que ver con el verdadero Desafío, voy a intentar (no sé muy bien cómo empezar) explicaros cómo reviento la fase 3. No sé lo que tardaré porque no voy bien de tiempo, pero algo haré antes de que empiece el siguiente. Eso sí, no os hagáis muchas ilusiones, es todo trivial y muy poco elegante.

  3. Aunque te cueste creerlo, Super, no pude plantear el problema de la caja y los candados como tal porque no lo conocía. Ya había visto muchas veces el término “candado” o figuras con llaves y candados para explicar algoritmos criptográficos, pero jamás se me ocurrió que pudiera plantearse el problema sin informática como vehículo. Cuando te referiste a él en un email me dije “Que bueno”. Pero ya era tarde. Te doy la razón en que como desafío, hubiera sido más ingenioso el problema sin informática. Y desde luego, mucho más ameno y menos laborioso para todos.

    Pero discrepo en que al plantearlo como informática la lógica te lleve a la solución. Cierto que sin informática es una auténtica genialidad dar con la solución. Pero si das con ella, es la única posibilidad. La informática hace más fácil que se te ocurra (digamos que quita mérito a la genialidad), pero te abre otras posibilidades. Tanto Rubenman como tu empezastéis pensando que podría desencriptarse directamente el primer mensaje.

    No se. Es posible que si pudiera volver para atrás decidiera plantear el problema sin informática. Pero nos hubiéramos perdido todo lo que ha pasado en el blog. A mi el sobreesfuerzo me ha compensado, porque me llevo muchas cosas de este desafío. Me han quedado mucho más claros los conceptos criptográficos al programarlos, he descubierto la página aspspider para publicar webs, he aprendido mucho al inventar estructuras para almacenar enteros grandes. Pero reconozco que como desafío, hubiera sido mejor sin informática por medio.

    Respecto a lo de si este protocolo lo inventó Shamir, ahora que lo dices probablemente no. Yo lo tomé de la wikipedia, de la página títulada “Protocolo tres envíos”, donde dice textualmente “El primer protocolo de tres pasos fue desarrollado por Adi Shamir en torno a 1980”. Pero es una página espantosa, mal redactada, y que da lugar a una interpretación errónea. Posiblemente lo original de Shamir sea usar un primo y dos claves privadas, pero no la idea de los candados. Como bien sabes, estuve mucho tiempo insistiendo en la idea equivocada de que el protocolo funcionaría entre dos personas que eligieran primos diferentes (a pesar de tus advertencias) y eso es lo que deduje leyendo la página.

    No puedo hablar por todos, pero por mi no pierdas mucho tiempo explicando tu reventador de la fase 3. Yo me conformo si me confirmas que tu método es probar todos los exponentes y me esbozas como evalúas informáticamente si una cadena de caracteres es un texto en castellano, y me dices como te las has arreglado para operar con enteros enormes.

    • Vas a dejar la web disponible. Me la coloco en favoritos.
      Una instrucción habla de descifrar cuando, creo, debería decir cifrar, aunque por el contexto se entiende perfectamente. Magnífico trabajo.

    • Estoy de acuerdo, las posibilidades laterales que da el enfoque informático han sido muy divertidas.

      En cuanto a la explicación prometida, te tomo la palabra y así me ahorro el trabajo de una explicación formal.
      Servirá tanto para Suschus, que me pidió detalles, como para tí, como para los curiosos en general.

      La página web que me permitió reventar la fase 3 no es otra que la de la fase 3.
      No quiero exagerar, pero estoy acostumbrado a leer manuales de instrucciones y ya me gustaría que todos fueran tan buenos como las explicaciones de Pardillano. Ya lo dice el mismo: “doy toda la información que puedo”.
      Y la da bien clarita, paso a paso, sin posibilidad de interpretación errónea.

      Por partes:
      Efectivamente, programo un bucle que en principio explora todos los D posibles, pero en la práctica no lo dejo terminar porque soy un tío suertudo y encuentro la clave enseguida.

      Para obtener una lista de todos los D posibles, sigo tus instrucciones:

      Primero saco todos los factores primos de p-1 y los meto en una lista.
      No me he molestado en usar librerías numéricas ni nada. Rudimentario a tope.
      Para sacar la lista de divisores primos de un número n, voy probando divisores empezando con el 2 y si la division es entera la efectuo (voy reduciendo n) tantas veces como sea entera y voy metiendo el mismo número de veces ese divisor en la lista. Cuando la división sucesiva ya no sea entera, aumento en uno el divisor y repito.
      Cuando el divisor supera la raiz cuadrada del número a factorizar, paro. La lista contendrá los factores primos (con repeticiones). Finalmente, convierto la lista en un conjunto (contenedor abstracto que no permite repeticiones), y ya tengo mi lista de factores primos de p-1.

      Luego preparo un bucle que vaya dando valores a E desde 0 hasta p-1 y obtengo por el mismo procedimiento una lista de los factores primos de cada E.
      Comparo las listas de factores de p-1 y E, y si no hay factores comunes, meto el E válido en otra lista “E_buenos”.

      Cuando ya tengo todos los E_buenos, preparo otro bucle anidado que para cada E bueno va dando valores a D entre 0 y p-1. Dentro del bucle compruebo si E*D modulo P-1 es igual a 1. La comprobación no es nada misteriosa, el código (Python) es:
      if (e*d)%(p-1)==1:
      donde % es el operador módulo (el resto de la división).
      Si la comprobación es afirmativa, ya tenemos el D pareja del E. Meto la parejita en otra lista de parejas buenas que llamo “buenos” y aborto el bucle interno y paso a probar el siguiente E.
      Cuando acaba el bucle externo, el resultado es una lista de 19992 parejitas que puedo podar un poco porque a Pardillano no le gustan los E inferiores a 1001 (manías). Esto elimina las primeras 492 entradas de la lista “buenos”, y también podría eliminar la última (E=40581,D=40581), que al ser simétrica no se puede usar para el desafío, pero no me molesto. Esto me deja con 19499 parejitas E,D. que, en rigor son la mitad de 19498 porque por cada pareja E,D hay otra igual D,E (recordemos que el algoritmo es conmutativo), pero no me molesto en reducir nada y trabajo con la lista entera.

      Una vez acabados los trabajos preliminares, me dedico a intentar decodificar el mensaje usando todos los D de la lista, de uno en uno. Para ello, sigo los pasos literales de Pardillano, pero como esto está resultando muy largo, sigo con otro mensaje.

  4. Lo vi tan difícil que pensé que si quería que nos comunicásemos habría “truco” y sonó la flauta. Luego siguiendo a Super a fisgonear.
    Muy bueno y he aprendido sobre un tema que desconocía por completo.
    En la fase 3 quise ponerme en ambos lados, pero no conseguí nada. Ahora probaré de nuevo según instrucciones.

  5. Sigo con la explicación. Ahora toca decodificar usando cada D de la lista. Preparo un bucle que recorra todos los D, y dentro de él:

    1-Convierto el texto en un número enorme en base 64 calculando para cada caracter c el resultado de:
    valor_letra(c)*(64**posicion))
    y sumando todos los valores obtenidos. (En esa línea, el ** es el operador potencia, y valor_letra(c) me devuelve el valor numérico de la letra dentro del alfabeto.

    2-Convierto el número enorme anterior a base p. Para ello, más código rudimentario (nada de librerías optimizadas). Voy dividiendo por p, y quedándome con todos los restos y el último cociente. Exactamente igual que cuando aprendimos en la escuela a pasar un número a base 2. Todos esos “dígitos” en base p los guardo en una lista.

    Estos dos primeros pasos no dependen de D, así que deberían estar fuera del bucle para evitar tener que recalcularlos 19000 y pico veces, pero me dí cuenta tarde y no me he molestado en corregirlo. Ya os avisé que era una chapuza hecha a toda prisa.

    3-Por cada “dígito” del numero en base p lo elevamos a d y sacamos el modulo p. Una vez más, nada misterioso ni librerías de ningún tipo:
    nuevo digito_=(digito**d)%p

    INCISO: Pardillano estará pensando que el cálculo de dígito elevado a d puede ser enorme. Digamos 35537 elevado a 40211 (números inventados). A quién le importa eso. No estoy seguro de qué dificultades ha estado encontrando con los números grandes, pero al menos en Python no hay que hacer nada. Igual me da que el primo sea 40583 o 2305843009213693951. El código es el mismo, solo que cuanto más grandes los números, más lento. Todos los lenguajes decentes puden al menos importar una librería externa que permita usar enteros arbitrariamente grandes, así que pienso que no es necesario complicarse la vida.
    Pardillano me comentó que estaba usando una técnica avanzada que permitía evitar la potenciación en este caso, me figuro que para acelerar el proceso. Yo no me he molestado en nada. Si hay que elevar, se eleva.

    Al final, tengo una lista con los dígitos convertidos.

    4-Interpreto esa lista como una cadena de dígitos en base p, y calculo el valor del número resultante. Para ello, por cada dígito hago:
    valor= digito*(p**posicion)
    Y al final sumo todos los valores.

    5-Paso el número a base 64 usando el mismo sistema que para la base p: dividir.

    6- Interpreto los dígitos del número en base 64 como caracteres usando el alfabeto, y ya tengo la cadena decodificada.

    Ahora se trata de comprobar si se puede leer o no. De no ser así, hay que elegir el siguiente D de la lista “buenos” y repetir el bucle otra vez más (quizá hasta 19498 veces).

    La comprobación automática (no me apetecía leer 19000 líneas) es absurdamente sencilla. Me baso en que el algoritmo de cifrado es bastante bueno repartiendo los caracteres dentro del espacio de 64 posibilidades que tenemos. Tanto es así, que el número de repeticiones (cualquier repetición) de caracteres en una línea codificada es escaso.
    Como el caracter más abundante de los textos en español es el espacio, me limito a contar los espacios. Me he inventado una constante 10, de forma que si al dividir la longitud de la cadena por el número de espacios sale un número superior a 10, considero que hay pocos espacios.
    Si la línea tiene suficientes espacios, la imprimo junto con su D correspondiente (sin abortar el bucle por si acaso, que sigue probando otros D).

    Mi trabajo una vez lanzado el programa se limita a mirar de vez en cuando a ver si ha salido algo (o si el programa ha terminado), y si ha salido algo legible, abortar.

    Una técnica sucia: para acelerar un poco las cosas (explorar los 19000 se acerca en mi caso a las 4 horas, entre otras cosas por no optimizar nada), arranco una segunda copia del programa en paralelo con la lista “buenos” del revés. El efecto es que un programa explora desde el inicio de la lista y el otro desde el final. Esto hace que tenga que mirar de vez en cuando las dos salidas, pero reduce el peor caso a la mitad (menos de dos horas).

    En la práctica, lo habitual en mi caso ha sido obtener el texto decodificado en media hora, junto con su D correspondiente. Y sólo en un caso he visto una cadena impresa que no fuera el mensaje correctamente decodificado, así que pienso que la cuenta de espacios funciona muy bien. Supongo que combinándola con la cuenta de “e” (el segundo caracter más popular), sería prácticamente infalible.

    Lo poco que queda lo hago a mano porque me costaba menos que poner la máquina a hacerlo.

    Busco en la lista “buenos” la pareja E asociada al D del mensaje decodificado. Armado con este E, me voy a la página de la fase 3 de Pardillano, escribo cualquier cosa en la contraseña, y pulso el botón. Observo qué E corresponde a lo tecleado. Si necesito un E mayor, alargo la contraseña, o bien agrando algún caracter de la misma (lo cambio por otro de mayor valor en el alfabeto). Si necesito un E menor, al revés. Si el escalon al agrandar o disminuir es demasiado grande porque el valor que busco se lo salta, elijo otro caracter e intento buscar en la dirección apropiada.

    Jugando así con la contraseña, en un par de minutos agrandando y disminuyendo caracteres, obtengo una contraseña falsa totalmente equivalente a la original del remitente.
    Ya sólo queda codificar un mensaje nuevo con la clave reventada y hablar con el remitente “en su propia clave”.

    Algunos ejemplos de las claves equivalentes que he reventado:
    Para Suschus (que fue el primero en caer), las verdaderas claves internas son E=6969 y D=32907. Cualquiera de las siguientes contraseñas sirve:
    00000000000001a
    9999999999999TE
    9999999999999ES
    8131000111111zX
    9eCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

    Para Rubenman (E=2925, D=17093):
    00000002

    Para Pardillano (E=7963, D=35873):
    910000000000001k

    En conclusión, el resumen de todo esto es que:
    1- El espacio de 19000 contraseñas diferentes posibles es demasiado pequeño para ser considerado seguro.
    2- Soy un chapucero, y un vago. Estoy seguro de que puedo acelerar mi programa tranquilamente en un factor de 100 optimizando técnicas y pasando de Python a C++, pero no me ha parecido que mereciera la pena. Desgraciadamente para Pardillano, mi programa es una transcripción literal de las explicaciones de su algoritmo, y no usa ninguna técnica interesante, así que no creo que pueda obtener nada útil.

    En cualquier caso, le mando a Pardillano por correo el programa completo. Si alguien más está interesado, que lo diga. Me da vergüenza enseñarlo, pero al menos servirá para que veáis lo tonto que soy

    Si ha quedado alguna duda, preguntad.

  6. Yo sólo hago llegar una sugerencia, antes de que patentéis vuestra idea, añadir el boton “clear” de limpieza.
    Otra cuestión, llega pronto otro desafío, pero no tengo ningún problema en que compatibilicéis la cuestión con lo que habéis dejado.
    Y otra más, no hay reservas de desafíos. Bueno, sí que tengo un par en mente pero no los puedo sacar ahora porque en el verano me va muy mal y prefiero reservarlos para la vuelta.
    ¿Tenéis alguno vosotros?. Ir pensando como capeamos el mes de agosto.

    • Yo llevo pensando un par de semanas. Tengo una propuesta que no me gusta mucho porque no tiene demasiada gracia.

      La poca gracia que tiene es porque he sacado el problema de un libro de un matemático que no encuentra una solución analítica y acaba atacando el problema con una simulación. Es un ejemplo didáctico de ataque a un problema difícil usando un ordenador, pero el caso es que el tipo confiesa que no ha encontrado la solución analítica e invita a los lectores a que quien lo consiga se la envíe y la incluirá en la siguiente edición.
      Finalmente, propone una complicación al problema y lo deja como ejercicio para el ordenador.

      Hasta aquí todo normal, pero…
      En mi indocumentada opinión, el problema no es difícil. Estoy seguro de que el autor ha recibido un aluvión de soluciones.
      Creo que incluso la versión complicada es perfectamente factible sin usar ordenador. (Aunque esto último aún no lo tengo claro del todo)

      No sé qué pensar. Hace falta una idea más o menos feliz, pero es que el problema no tiene demasiada chicha.
      Si llega el caso, ya lo propondré, pero que no haya grandes expectativas.
      A ver si me aclaro con la complicación.

  7. Respecto al programa de Super, teniendo en cuenta que a mi me tarda 30 segundos para codificar una sola vez un texto de 50 caracteres, si yo hiciera lo que hace él y encontrara el D bueno a los 10000 intentos, tardaría aproximadamente 3,5 días.

    ¿Quien es el que necesita optimizar su software?

    Respecto a desafíos futuros, yo tengo ideas sin desarrollar, pero en Agosto me será imposible sacar tiempo y medios para ser desafiante. Y ya veremos si puedo participar en lo que propongáis.

    Pero para septiembre si que podré proponer alguna cosa.

  8. Un desafío muy entretenido y original. Y la habilidad de SPZ con el ordenador, pese a lo que él piensa, es excepcional, al menos para mí que sólo me defiendo con hojas de cálculo.

    • Me gusta fardar como al que más, pero no es cierto. Aunque esta vez he salido airoso, Pardillano me da cien vueltas (en esto y en otras cosas). La historia me da la razón.
      Bueno, 101 vueltas, porque él domina también la hoja de cálculo y yo no me aclaro. Si como tú mismo dices, te defiendes con ella, ya me adelantas en algo.
      Eso sí, a pesado no me gana nadie, y para demostrarlo, un poquito más de texto, que últimamente he hablado poco:

      En este desafío he jugado con mucha ventaja. No sólo no tenía que inventar nada, sino que era libre para hacerlo como me diese la gana. Pardillano quería compartir con todos su codificador/decodificador, asi que ha tenido que elegir unas herramientas que se lo permitieran. Ha decidido que nuestra comodidad de uso era más importante que su libertad de elección y ha creado su nueva web, compatible con todos los sistemas.

      Esta herramienta de acceso universal tiene muchísimas ventajas, y seguro que dará mucho juego en el futuro. El precio que ha tenido que pagar en este Desafío ha sido la falsa impresión de que mis habilidades superaban a las suyas, pero ha sido sólo porque mis herramientas en la sombra estaban mejor adaptadas (he de decir que por pura casualidad) para este problema en particular. He visto su programa, y, en comparación, el mío es mucho más rudimentario. Él ha tenido que trabajar mucho más que yo, es de justicia que se sepa.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s