SlideShare une entreprise Scribd logo
1  sur  13
Télécharger pour lire hors ligne
Problema Recruitingmsa
Razonamiento y resolución del problema
Presentación del problema
• Dada la siguiente función de Python:
• Al ejecutar la siguiente llamada se produce un Overflow
• my_func("0123456789012345678901234567890123456789",
9999999999999999)
def my_func(r, n):
for i in xrange(n): r = hashlib.sha1(r[:9]).hexdigest()
return r
Análisis del origen del problema
• Dado el trace de la excepción sabemos que la excepción se lanza al intentar
evaluar un objeto como entero pero que el mismo es demasiado grande
para convertirse a entero
• De los valores que pasamos solo uno de estos es un objeto que representa
un numero:
• Siendo que es xrange quien recibe ese valor buscamos su definición en la
librería de Python y encontramos que: The C implementation of Python
restricts all arguments to native C longs (“short” Python integers), and also
requires that the number of elements fit in a native C long. If a larger range
is needed, an alternate version can be crafted
Análisis de la lógica de la función
• Antes de analizar una resolución decidí analizar la lógica de la función
realizando algunas pruebas rápidas.
• Lo primero que identifico según la información enviada es que los
hashes aparentan ser sumatorios, por lo cual quiero comprobar esto
mediante pequeñas pruebas con algunas variaciones, de ser asi
podremos implementar una función recursiva.
Pruebas de logica
• Realice las siguientes pruebas para llegar a la conclusión de que es
sumatorio.
Algunos ejemplos concretos de la función:
my_func("0123456789012345678901234567890123456789", 0) = 0123456789012345678901234567890123456789
my_func("0123456789012345678901234567890123456789", 1) = 9a7149a5a7786bb368e06d08c5d77774eb43a49e
my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9
my_func("9a7149a5a7786bb368e06d08c5d77774eb43a49e", 1) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9
#Prueba si los saltos son sumatorios, y con numeros pares
my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9
my_func("0123456789012345678901234567890123456789", 4) = 09c39ceafeec24479c8598ee622a399b2e753e2b
my_func("747c9a467f90021e5d213e2f6d27ccf82e25d0c9", 2) = 09c39ceafeec24479c8598ee622a399b2e753e2b #correcto
#Al parecer sumatorios, probando si es logico con numeros impares
my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9
my_func("0123456789012345678901234567890123456789", 5) = 14b51f5ee4250c7f238363b604dd5201ba2bbeb7
my_func("747c9a467f90021e5d213e2f6d27ccf82e25d0c9", 3) = 14b51f5ee4250c7f238363b604dd5201ba2bbeb7 #correcto
#Prueba con pares mas complejos
my_func("0123456789012345678901234567890123456789", 10) = 2dd637caf35019298ca1909e0ea644d5babadbff
my_func("0123456789012345678901234567890123456789", 98) = 168c666606aa8feb0c91a420e68cbe32d841eb5b
my_func("2dd637caf35019298ca1909e0ea644d5babadbff", 88) = 168c666606aa8feb0c91a420e68cbe32d841eb5b #correcto
#Prueba con impares mas complejos
my_func("0123456789012345678901234567890123456789", 27) = eef3f00f84909ec5e3177fd86d5e6550ac782d7f
my_func("0123456789012345678901234567890123456789", 319) = 92b1f1f3e8447874272de50f22ccd99b9baaebb9
my_func("eef3f00f84909ec5e3177fd86d5e6550ac782d7f", 319-27) = 92b1f1f3e8447874272de50f22ccd99b9baaebb9 #correcto
Pruebas de logica – análisis de resultados
• Realizando las pruebas de lógicas encontramos que los tiempos para
resolver linealmente este proceso serian demasiado largos, por otro
lado para generar los nuevos hashes solo se están utilizando los
primeros 9 elementos del string, por lo cual existe una amplia
posibilidad de que se repitan los resultados antes de llegar al numero
mas grande considerado como entero (mas detalle en un próximo
slide).
• Para avanzar con nuevas pruebas de lógicas hacemos una pequeña
modificación en el código que guarde hashes previos en una lista
temporal, si es factible encontrar colisiones repetitivas de los hashes
en un tiempo aceptable.
Investigacion
• Buscando información se encuentra acerca de los ciclos y algoritmos
para encontrarlos:
• https://en.wikipedia.org/wiki/Cycle_detection
• http://pythoncentral.io/hashing-strings-with-python/
Nuevo código para mas pruebas de lógica
import sys
import hashlib
def my_func(r, n):
temp = [] # lista temporal de hashes
strikes = 0 # utilizado para contar las repeticiones
if isinstance( n, long ): # esta prueba se hizo para probar una solucion
print "calling recursion" # recursiva, pero los tiempos se extienden
r = my_func(r, n-sys.maxint) # demasiado, y con el planteo original
n = sys.maxint # se supero el limite de recursividad
for i in xrange(n):
r = hashlib.sha1(r[:9]).hexdigest()
if r in temp: # chequeamos si ya esta en la lista temporal
print str(i) + " - " + r + " index " + str(temp.index(r))
# temp.index lo usamos para saber la distancia entre repeticiones
strikes += 1 # aumentamos los strikes
temp.append(r) # luego de imprimir en pantalla la info lo agregamos
if strikes == 3:
break # 3 strikes y cortamos la ejecucion
return r
Resultados de las nuevas pruebas
• Encontramos que si se encontró un ciclo de colisiones en un tiempo
aceptable:
Las colisiones se dan en rangos de 109019 repeticiones a partir de la ocurrencia 264088 (Es decir 155069 +
264088).
Se creo una pequeña modificación al código para verificar esta distancia:
Resolución del problema
• Tal como se menciona en la librería sabemos que en caso de necesitar
utilizar xrange con un numero superior a un int necesitamos crear un
desarrollo propio. Lo primero que debemos averiguar es según
nuestra plataforma cual es el numero máximo considerado como
entero, lo que se puede obtener mediante la librería “sys”:
• Solo con el punto anterior no bastaría, ya que los tiempos para correr
esta función con un numero como sys.maxint se extendería
demasiado. Por eso se busco otras alternativas y encontramos así que
existe colisiones a partir de la ocurrencia 264088 que condicen con el
hash 155069, es decir, a partir de 155069 cada 109019 hashes
calculados aparecen colisiones
Resolución del problema - 2
• Dados los puntos anteriores se modifico el código original para que
cualquier n mayor a 264088 (155069+109019) se reduzca a un
numero entero entre 155069 y 264087 y encontrar su colisión
correspondiente.
• La función utilizara para resolver el problema es:
• def my_func(r, n):
if n >= 264088: # 155069+109019
n = int((n-((n/109019)*109019))+109019)
for i in xrange(n):
r = hashlib.sha1(r[:9]).hexdigest()
return r
Resultado de la ejecucion
• El resultante a correr
my_func("0123456789012345678901234567890123456789",
9999999999999999) fue:
'd82fd2b1b9c82df7c199ad716033aeb33785d2a0’
Mejoras en performance
• Dado que cualquier n superior a 264088 es reducido a un numero
entre 155069 y 264087 los tiempos de ejecución se reducen
drásticamente.
• Ejecución previa modificación:
• Ejecución luego de la modificación:

Contenu connexe

Tendances (20)

Guia final so
Guia final soGuia final so
Guia final so
 
2 eficiencia
2 eficiencia2 eficiencia
2 eficiencia
 
Ingenieria de-control-febrero-2012
Ingenieria de-control-febrero-2012Ingenieria de-control-febrero-2012
Ingenieria de-control-febrero-2012
 
6.funciones y recursividad en c++
6.funciones y recursividad en c++6.funciones y recursividad en c++
6.funciones y recursividad en c++
 
Taller 1 de estructuras
Taller 1 de estructurasTaller 1 de estructuras
Taller 1 de estructuras
 
Unidad 4 est. dat. recursividad
Unidad 4  est. dat. recursividadUnidad 4  est. dat. recursividad
Unidad 4 est. dat. recursividad
 
Presentación arraysobjetos
Presentación arraysobjetosPresentación arraysobjetos
Presentación arraysobjetos
 
Funciones str
Funciones strFunciones str
Funciones str
 
Ejercicios
EjerciciosEjercicios
Ejercicios
 
T7 Alg Mult Matr
T7 Alg Mult MatrT7 Alg Mult Matr
T7 Alg Mult Matr
 
Evaluación prog iii try catch
Evaluación prog iii try catchEvaluación prog iii try catch
Evaluación prog iii try catch
 
Análisis de complejidad introducción notación big o
Análisis de complejidad   introducción notación big oAnálisis de complejidad   introducción notación big o
Análisis de complejidad introducción notación big o
 
Practica 2
Practica 2Practica 2
Practica 2
 
Recursividad
RecursividadRecursividad
Recursividad
 
Proyecto redes
Proyecto redesProyecto redes
Proyecto redes
 
03 tda1 t2018
03 tda1 t201803 tda1 t2018
03 tda1 t2018
 
Propiedades funciones principales
Propiedades funciones principalesPropiedades funciones principales
Propiedades funciones principales
 
Semaforos
SemaforosSemaforos
Semaforos
 
Recursividad
RecursividadRecursividad
Recursividad
 
Clase2_Python-CTIC
Clase2_Python-CTICClase2_Python-CTIC
Clase2_Python-CTIC
 

Similaire à Análisis de colisiones de hashes sha1 y resolviendo un problema de hashing recursivo con xrange y variables numéricas long.

PROY 3: VERIFICACION DE PALINDROMOS
PROY 3: VERIFICACION DE PALINDROMOSPROY 3: VERIFICACION DE PALINDROMOS
PROY 3: VERIFICACION DE PALINDROMOSgaby
 
Teoría De La Complejidad Algoritmica
Teoría De La Complejidad AlgoritmicaTeoría De La Complejidad Algoritmica
Teoría De La Complejidad AlgoritmicaRolf Pinto
 
20 algoritmos
20 algoritmos20 algoritmos
20 algoritmosdiego
 
Matlab (1)
Matlab (1)Matlab (1)
Matlab (1)numpad
 
Matlab
MatlabMatlab
Matlabford81
 
Metodo de la secante en scilab
Metodo de la secante en scilabMetodo de la secante en scilab
Metodo de la secante en scilabTensor
 
Cap 02.1 analisis de las estructuras de control(1)
Cap 02.1   analisis de las estructuras de control(1)Cap 02.1   analisis de las estructuras de control(1)
Cap 02.1 analisis de las estructuras de control(1)Lio Alva
 
Metodo de la secante en scilab
Metodo de la secante en scilabMetodo de la secante en scilab
Metodo de la secante en scilabTensor
 
Sobrecarga de operadores
Sobrecarga de operadoresSobrecarga de operadores
Sobrecarga de operadoresr0na91
 
Jflambert lyada - ayudantia matematicas discretas
Jflambert   lyada - ayudantia matematicas discretasJflambert   lyada - ayudantia matematicas discretas
Jflambert lyada - ayudantia matematicas discretasFrancisco Lambert Obediente
 

Similaire à Análisis de colisiones de hashes sha1 y resolviendo un problema de hashing recursivo con xrange y variables numéricas long. (20)

PROY 3: VERIFICACION DE PALINDROMOS
PROY 3: VERIFICACION DE PALINDROMOSPROY 3: VERIFICACION DE PALINDROMOS
PROY 3: VERIFICACION DE PALINDROMOS
 
Teoría De La Complejidad Algoritmica
Teoría De La Complejidad AlgoritmicaTeoría De La Complejidad Algoritmica
Teoría De La Complejidad Algoritmica
 
Palindromos
PalindromosPalindromos
Palindromos
 
Tema4
Tema4Tema4
Tema4
 
Notación Asintótica
Notación AsintóticaNotación Asintótica
Notación Asintótica
 
20 algoritmos
20 algoritmos20 algoritmos
20 algoritmos
 
Informe
InformeInforme
Informe
 
Matlab (1)
Matlab (1)Matlab (1)
Matlab (1)
 
Matlab
MatlabMatlab
Matlab
 
Metodo de la secante en scilab
Metodo de la secante en scilabMetodo de la secante en scilab
Metodo de la secante en scilab
 
Cap 02.1 analisis de las estructuras de control(1)
Cap 02.1   analisis de las estructuras de control(1)Cap 02.1   analisis de las estructuras de control(1)
Cap 02.1 analisis de las estructuras de control(1)
 
Metodo de la secante en scilab
Metodo de la secante en scilabMetodo de la secante en scilab
Metodo de la secante en scilab
 
Gauss
GaussGauss
Gauss
 
Gauss
GaussGauss
Gauss
 
AnáLisis De Algoritmos1
AnáLisis De Algoritmos1AnáLisis De Algoritmos1
AnáLisis De Algoritmos1
 
AnáLisis De Algoritmos1
AnáLisis De Algoritmos1AnáLisis De Algoritmos1
AnáLisis De Algoritmos1
 
Sobrecarga de operadores
Sobrecarga de operadoresSobrecarga de operadores
Sobrecarga de operadores
 
Complejidad Computacional
Complejidad ComputacionalComplejidad Computacional
Complejidad Computacional
 
Mathscript
MathscriptMathscript
Mathscript
 
Jflambert lyada - ayudantia matematicas discretas
Jflambert   lyada - ayudantia matematicas discretasJflambert   lyada - ayudantia matematicas discretas
Jflambert lyada - ayudantia matematicas discretas
 

Análisis de colisiones de hashes sha1 y resolviendo un problema de hashing recursivo con xrange y variables numéricas long.

  • 1. Problema Recruitingmsa Razonamiento y resolución del problema
  • 2. Presentación del problema • Dada la siguiente función de Python: • Al ejecutar la siguiente llamada se produce un Overflow • my_func("0123456789012345678901234567890123456789", 9999999999999999) def my_func(r, n): for i in xrange(n): r = hashlib.sha1(r[:9]).hexdigest() return r
  • 3. Análisis del origen del problema • Dado el trace de la excepción sabemos que la excepción se lanza al intentar evaluar un objeto como entero pero que el mismo es demasiado grande para convertirse a entero • De los valores que pasamos solo uno de estos es un objeto que representa un numero: • Siendo que es xrange quien recibe ese valor buscamos su definición en la librería de Python y encontramos que: The C implementation of Python restricts all arguments to native C longs (“short” Python integers), and also requires that the number of elements fit in a native C long. If a larger range is needed, an alternate version can be crafted
  • 4. Análisis de la lógica de la función • Antes de analizar una resolución decidí analizar la lógica de la función realizando algunas pruebas rápidas. • Lo primero que identifico según la información enviada es que los hashes aparentan ser sumatorios, por lo cual quiero comprobar esto mediante pequeñas pruebas con algunas variaciones, de ser asi podremos implementar una función recursiva.
  • 5. Pruebas de logica • Realice las siguientes pruebas para llegar a la conclusión de que es sumatorio. Algunos ejemplos concretos de la función: my_func("0123456789012345678901234567890123456789", 0) = 0123456789012345678901234567890123456789 my_func("0123456789012345678901234567890123456789", 1) = 9a7149a5a7786bb368e06d08c5d77774eb43a49e my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9 my_func("9a7149a5a7786bb368e06d08c5d77774eb43a49e", 1) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9 #Prueba si los saltos son sumatorios, y con numeros pares my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9 my_func("0123456789012345678901234567890123456789", 4) = 09c39ceafeec24479c8598ee622a399b2e753e2b my_func("747c9a467f90021e5d213e2f6d27ccf82e25d0c9", 2) = 09c39ceafeec24479c8598ee622a399b2e753e2b #correcto #Al parecer sumatorios, probando si es logico con numeros impares my_func("0123456789012345678901234567890123456789", 2) = 747c9a467f90021e5d213e2f6d27ccf82e25d0c9 my_func("0123456789012345678901234567890123456789", 5) = 14b51f5ee4250c7f238363b604dd5201ba2bbeb7 my_func("747c9a467f90021e5d213e2f6d27ccf82e25d0c9", 3) = 14b51f5ee4250c7f238363b604dd5201ba2bbeb7 #correcto #Prueba con pares mas complejos my_func("0123456789012345678901234567890123456789", 10) = 2dd637caf35019298ca1909e0ea644d5babadbff my_func("0123456789012345678901234567890123456789", 98) = 168c666606aa8feb0c91a420e68cbe32d841eb5b my_func("2dd637caf35019298ca1909e0ea644d5babadbff", 88) = 168c666606aa8feb0c91a420e68cbe32d841eb5b #correcto #Prueba con impares mas complejos my_func("0123456789012345678901234567890123456789", 27) = eef3f00f84909ec5e3177fd86d5e6550ac782d7f my_func("0123456789012345678901234567890123456789", 319) = 92b1f1f3e8447874272de50f22ccd99b9baaebb9 my_func("eef3f00f84909ec5e3177fd86d5e6550ac782d7f", 319-27) = 92b1f1f3e8447874272de50f22ccd99b9baaebb9 #correcto
  • 6. Pruebas de logica – análisis de resultados • Realizando las pruebas de lógicas encontramos que los tiempos para resolver linealmente este proceso serian demasiado largos, por otro lado para generar los nuevos hashes solo se están utilizando los primeros 9 elementos del string, por lo cual existe una amplia posibilidad de que se repitan los resultados antes de llegar al numero mas grande considerado como entero (mas detalle en un próximo slide). • Para avanzar con nuevas pruebas de lógicas hacemos una pequeña modificación en el código que guarde hashes previos en una lista temporal, si es factible encontrar colisiones repetitivas de los hashes en un tiempo aceptable.
  • 7. Investigacion • Buscando información se encuentra acerca de los ciclos y algoritmos para encontrarlos: • https://en.wikipedia.org/wiki/Cycle_detection • http://pythoncentral.io/hashing-strings-with-python/
  • 8. Nuevo código para mas pruebas de lógica import sys import hashlib def my_func(r, n): temp = [] # lista temporal de hashes strikes = 0 # utilizado para contar las repeticiones if isinstance( n, long ): # esta prueba se hizo para probar una solucion print "calling recursion" # recursiva, pero los tiempos se extienden r = my_func(r, n-sys.maxint) # demasiado, y con el planteo original n = sys.maxint # se supero el limite de recursividad for i in xrange(n): r = hashlib.sha1(r[:9]).hexdigest() if r in temp: # chequeamos si ya esta en la lista temporal print str(i) + " - " + r + " index " + str(temp.index(r)) # temp.index lo usamos para saber la distancia entre repeticiones strikes += 1 # aumentamos los strikes temp.append(r) # luego de imprimir en pantalla la info lo agregamos if strikes == 3: break # 3 strikes y cortamos la ejecucion return r
  • 9. Resultados de las nuevas pruebas • Encontramos que si se encontró un ciclo de colisiones en un tiempo aceptable: Las colisiones se dan en rangos de 109019 repeticiones a partir de la ocurrencia 264088 (Es decir 155069 + 264088). Se creo una pequeña modificación al código para verificar esta distancia:
  • 10. Resolución del problema • Tal como se menciona en la librería sabemos que en caso de necesitar utilizar xrange con un numero superior a un int necesitamos crear un desarrollo propio. Lo primero que debemos averiguar es según nuestra plataforma cual es el numero máximo considerado como entero, lo que se puede obtener mediante la librería “sys”: • Solo con el punto anterior no bastaría, ya que los tiempos para correr esta función con un numero como sys.maxint se extendería demasiado. Por eso se busco otras alternativas y encontramos así que existe colisiones a partir de la ocurrencia 264088 que condicen con el hash 155069, es decir, a partir de 155069 cada 109019 hashes calculados aparecen colisiones
  • 11. Resolución del problema - 2 • Dados los puntos anteriores se modifico el código original para que cualquier n mayor a 264088 (155069+109019) se reduzca a un numero entero entre 155069 y 264087 y encontrar su colisión correspondiente. • La función utilizara para resolver el problema es: • def my_func(r, n): if n >= 264088: # 155069+109019 n = int((n-((n/109019)*109019))+109019) for i in xrange(n): r = hashlib.sha1(r[:9]).hexdigest() return r
  • 12. Resultado de la ejecucion • El resultante a correr my_func("0123456789012345678901234567890123456789", 9999999999999999) fue: 'd82fd2b1b9c82df7c199ad716033aeb33785d2a0’
  • 13. Mejoras en performance • Dado que cualquier n superior a 264088 es reducido a un numero entre 155069 y 264087 los tiempos de ejecución se reducen drásticamente. • Ejecución previa modificación: • Ejecución luego de la modificación: