1

演習として、MD5 を PHP に実装しようとしています。PHPにはこのための組み込み関数があることは知っていますが、実際のソースを読んで実行し、調査したいと思います。このスクリプトは、適切なセクションのコメントを解除し (メッセージ パディングを有効にするため)、それに応じて配列をフォーマットする (私のバージョンの PHP との互換性のため) 場合にうまく機能することがわかりました。ただし、生成されたハッシュは、正しい長さにもかかわらず、MD5 ではありません。たとえば、長さゼロの文字列の MD5 ハッシュは次のようになります。

d41d8cd98f00b204e9800998ecf8427e

しかし、同じスクリプトによって返されるハッシュは次のとおりです。

85bd946a585af9fd3fb9eda68707c1d8

他の文字列も試しましたが、相関関係はありません。私は MD5 を研究してきたので、MD5 がどのように機能するかについて十分な知識を持っています。私はスクリプトを調査してきましたが、正当なようです。このスクリプトが MD5 を返さない理由を発見するという挑戦のために、私は別の人に叫び声を上げていると思います。

4

1 に答える 1

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)) ;
}

数式の類似性とビット マスクの存在 (または不在) を示すために、行 2 と対比するために、意図的に行 4 に複数のスペースを残しました。

3 進数形式:

 return ($x < 0) ? (($x << $c) | abs( ((pow(2, $c)) * -1) - 
        ($x >> (32 - $c)))) : (($x << $c) | ($x >> (32 - $c)));
于 2016-10-25T13:57:42.967 に答える