2016-10-18 11 views
1

Как упражнение, я пытаюсь реализовать MD5 в PHP. Я знаю, что PHP имеет встроенную функцию для этого, но я хотел бы читать, запускать и изучать рабочий источник. Я нашел this script, который отлично работает, когда соответствующие разделы раскоментированы (чтобы включить заполнение сообщений), и массивы соответственно отформатированы (для совместимости с моей версией PHP). Однако созданный хэш - несмотря на правильную длину - не MD5. Например, хэш MD5 для строки нулевой длины должен быть:Сценарий MD5 в PHP

d41d8cd98f00b204e9800998ecf8427e

но хэш возвращенного сценарием то же самое:

85bd946a585af9fd3fb9eda68707c1d8

Я пробовал другие строки но корреляции нет. Я изучаю MD5, поэтому имею разумные знания о том, как это работает. Я допрашивал сценарий, но это кажется законным. Думаю, я даю крик другому, чтобы понять, почему этот сценарий не возвращает MD5.

+0

'моя версия PHP' PHP7? – JOUM

+1

Я запустил его, и он выплюнул множество «неопределенных индексов», поэтому я сдался прямо там. – AbraCadaver

+0

Привет, к сожалению, я запускаю старую версию - 5.3.28, однако она все равно должна возвращать подлинный хеш MD5. Не думайте, что вы сможете сказать мне, вернет ли этот скрипт подлинный MD5 хэш в 7? – James

ответ

2

Этот сценарий не возвращал подлинные хэши MD5, потому что возникла проблема с функцией вращения.

В настоящее время PHP не предлагает собственные побитовые функции (-ы) вращения. Тем не менее, побитное вращение может быть достигнуто путем объединения результата сдвига влево и результата правого сдвига. Однако при правых смещениях битов на отрицательных целых знаках знаковый бит сдвигается для сохранения знака операнда; это имеет нежелательные последствия и преодолевается с помощью битовой маски.

Где $x - это входное значение, а $c - количество бит, которое нужно сдвинуть. Все значения 32-бит.

Оригинальный код:

`return ($x << $c) | ($x >> (32 - $c));` 

Новый код:

if($x < 0){ 
    return ($x << $c) | abs(((pow(2, $c)) * -1) - ($x >> (32 - $c))); 
} else { 
    return ($x << $c) |       ($x >> (32 - $c)) ; 
} 

Я намеренно оставил несколько пробелов в строке 4 контрастировать с линией 2, чтобы показать формулу сходства и присутствия (или отсутствие) битовой маски.

троичной отформатирован:

return ($x < 0) ? (($x << $c) | abs(((pow(2, $c)) * -1) - 
     ($x >> (32 - $c)))) : (($x << $c) | ($x >> (32 - $c)));