Considere que tiene una función hash que toma cadenas de longitud y devuelve cadenas de longitud y tiene la buena propiedad de que es resistente a colisiones , es decir, es difícil encontrar dos cadenas diferentes con el mismo hash .
Ahora le gustaría construir una nueva función hash que tome cadenas de longitud arbitraria y las asigne a cadenas de longitud , sin dejar de ser resistente a colisiones.
Por suerte para ti, ya en 1979 se publicó un método ahora conocido como la construcción Merkle-Damgård que logra exactamente esto.
La tarea de este desafío será implementar este algoritmo, por lo que primero veremos una descripción formal de la construcción Merkle-Damgård, antes de pasar por un ejemplo paso a paso que debería mostrar que el enfoque es más simple que Puede aparecer al principio.
Dado un número entero , una función hash como se describió anteriormente y una cadena de entrada de longitud arbitraria, la nueva función hash hace lo siguiente:
- Establecer, la longitud de , y divida en trozos de longitud , llenando el último fragmento con ceros finales si es necesario. Esto produce muchos trozos que están etiquetados como .
- Añadir un ataque y un trailing trozo y , donde es una cadena que consta de n ceros y c m + 1 es n en binario, rellenado con principales ceros a longitud n .
- Ahora aplique iterativamente al fragmento actual adjuntado al resultado anterior : , donde . (Este paso podría ser más claro después de ver el ejemplo a continuación).
- La salida de es el resultado final .
La tarea
Escriba un programa o función que tome como entrada un número entero positivo , una función hash como cuadro negro y una cadena no vacía devuelve el mismo resultado que en las mismas entradas.
Este es el código de golf , por lo que gana la respuesta más corta en cada idioma.
Ejemplo
Digamos , por lo que nuestra función hash toma cadenas de longitud 10 y devuelve cadenas de longitud 5.
- Dada una entrada de , obtenemos los siguientes fragmentos: , , y . Tenga en cuenta que necesita ser rellenado hasta la longitud 5 con un cero al final.
- es solo una cadena de cinco ceros y es cinco en binario ( ), rellenado con dos ceros a la izquierda.
- Ahora los fragmentos se combinan con :
- es nuestra salida.
Veamos cómo se vería esta salida dependiendo de algunas opciones 1 para :
- Si , es decir, solo devuelve cada segundo carácter, obtenemos:
Por lo tanto, debe ser la salida si dicha se da como función de caja negra. - Si simplemente devuelve los primeros 5 caracteres de su entrada, la salida de es . Del mismo modo, si devuelve los últimos 5 caracteres, la salida es .
- Si multiplica los códigos de caracteres de su entrada y devuelve los primeros cinco dígitos de este número, por ejemplo, , entonces .
1 Por simplicidad, esos realidad no son resistentes a colisiones, aunque esto no importa para probar su envío.
omgPzzles0
. Well chosen example input!