Предположим, у вас есть хеш-функция которая принимает строки длиной и возвращает строки длины и имеет приятное свойство - она устойчива к столкновениям , то есть трудно найти две разные строки с одинаковым хешем .
Теперь вы хотели бы создать новую хеш-функцию которая принимает строки произвольной длины и отображает их в строки длины , в то же время сохраняя устойчивость к столкновениям.
К счастью для вас, уже в 1979 году был опубликован метод, теперь известный как конструкция Меркля-Дамгарда, который достигает именно этого.
Задача этой задачи будет заключаться в реализации этого алгоритма, поэтому сначала мы рассмотрим формальное описание конструкции Меркля – Дамгарда, прежде чем перейти к пошаговому примеру, который должен показать, что подход проще, чем это может появиться сначала.
Учитывая некоторое целое число , хеш-функцию как описано выше, и входную строку произвольной длины, новая хеш-функция выполняет следующие действия:
- Установите, длина и разбиение на куски длины n , заполняя последний кусок завершающими нулями, если необходимо. Это дает m = ⌈ lмного кусков, которые помечены как.
- Добавьте начальный и конечный фрагменты и , где - строка, состоящая из нулей и - этодвоичное число , дополненноеначальныминулями до длины .
- Теперь итеративно применяем к текущему фрагменту добавленному к предыдущему результату : , где . (Этот шаг может быть более понятным после просмотра примера ниже.)
- Выход является конечным результатом .
Задание
Напишите программу или функцию, которая принимает в качестве входных данных положительное целое число , хеш-функцию качестве черного ящика и непустую строку и возвращает тот же результат, что и на тех же входах.
Это код-гольф , поэтому выигрывает самый короткий ответ на каждом языке.
пример
Допустим, , поэтому наша заданная хеш-функция принимает строки длиной 10 и возвращает строки длиной 5.
- Учитывая ввод , мы получаем следующие фрагменты: , , и . Обратите внимание, что необходимо дополнить до длины 5 с одним завершающим нулем.
- - это просто строка из пяти нулей, а - это пять в двоичном виде ( ), дополненная двумя ведущими нулями.
- Теперь куски объединяются с :
- is our output.
Let's have a look how this output would look depending on some choices1 for :
- If , 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!