Considerate si dispone di una funzione di hash che prende stringhe di lunghezza e restituisce stringhe di lunghezza ed ha la proprietà bello che è resistente collisione , vale a dire che è difficile trovare due stringhe differenti con lo stesso hash .
Ora vorresti costruire una nuova funzione hash che prende stringhe di lunghezza arbitraria e le mappa su stringhe di lunghezza , pur essendo resistente alle collisioni.
Fortunatamente per te, già nel 1979 è stato pubblicato un metodo ora noto come costruzione Merkle – Damgård che ottiene esattamente questo.
Il compito di questa sfida sarà quello di implementare questo algoritmo, quindi daremo prima un'occhiata a una descrizione formale della costruzione Merkle-Damgård, prima di passare attraverso un esempio passo-passo che dovrebbe mostrare che l'approccio è più semplice di potrebbe apparire all'inizio.
Dato un numero intero , una funzione hash come descritto sopra e una stringa di input di lunghezza arbitraria, la nuova funzione hash esegue le seguenti operazioni:
- Impostare , la lunghezza di , e dividere in blocchi di lunghezza , riempiendo l'ultimo blocco con zeri finali, se necessario. Questo produce molti pezzi che sono etichettati.
- Aggiungere un pezzo principale ed una posteriore e , dove è una stringa costituita zeri e è in binario, riempito con porta zeri alla lunghezza .
- Ora applica ripetutamente al blocco corrente aggiunto al risultato precedente : , dove . (Questo passaggio potrebbe essere più chiaro dopo aver visto l'esempio di seguito.)
- L'output di è il risultato finale .
L'obiettivo
Scrivere un programma o funzione che prende in ingresso un intero positivo , una funzione hash come scatola nera e una stringa non vuota e restituisce lo stesso risultato sugli stessi ingressi.
Questo è code-golf , quindi vince la risposta più breve in ogni lingua.
Esempio
Diciamo , quindi la nostra data funzione di hash prende stringhe di lunghezza 10 e restituisce stringhe di lunghezza 5.
- Dato un input di , otteniamo i seguenti blocchi: , , e . Nota che doveva essere imbottito alla lunghezza 5 con uno zero finale.
- is just a string of five zeros and is five in binary (), padded with two leading zeros.
- Ora i blocchi sono combinati con :
H ( H ( " 00000Progr " ) " ammin " ) " g Puz ") r
- is our output.
Let's have a look how this output would look depending on some choices1 for :
- , i.e. just returns every second character, we get:
So needs to be the output if such a is given as black box function. - If simply returns the first 5 chars of its input, the output of is . Similarly if returns the last 5 chars, the output is .
- If multiplies the character codes of its input and returns the first five digits of this number, e.g. , then .
1 For simplicity, those are actually not collision resistant, though this does not matter for testing your submission.
omgPzzles0
. Well chosen example input!