4

私はjavascriptでこの機能を持っています - 正しく動作します

// javascript
    function myhash(str) {
      var hash = 0;
      if (str.length == 0) return hash;
      for (var i = 0; i < str.length; i++) {
        oneChar = str.charCodeAt(i);
        hash = ((hash << 5) - hash) + oneChar;
        hash &= hash;
      }
      return hash;
    }

そして、この関数をPHPに書き直そうとしていますが、同じ入力に対して、JSからの出力とは異なる出力が得られます。

// php
      function myhash($str) {
        $hash = 0;
        if (strlen($str) == 0) return $hash;
        for ($i = 0; $i < strlen($str); $i++) {
          $oneChar = ord($str[$i]);
          $hash = (($hash << 5) - $hash) + $oneChar;
          $hash &= $hash;
        }
        return $hash;
      }

入力と出力の例:

console.log(myhash("example")); // output: -1322970774
echo myhash("example"); // output: 93166309738

誰が知っていますか、どこに問題があるのでしょうか? それらは同じように見えますが、明らかにそうではありません。

4

3 に答える 3

3

Javascriptの<<演算子は、数値パラメーターを IEEE 754 double ではなく、32 ビットの符号付き整数に変換します。

PHP コードを修正するには、(少なくとも) 操作の結果をマスクしてから、<<他の操作を行う必要があります。

以下のコードは、(64 ビット) MacOS X 10.8.4 で PHP 5.3.15 を使用して「example」の入力の JS コードと同じ結果を生成します。他のテスト ケースや 32 ビット バージョンの PHP では機能しない場合があります。

function myhash($str) {
  $hash = 0;
  if (strlen($str) == 0) return $hash;
  for ($i = 0; $i < strlen($str); $i++) {
    $oneChar = ord($str[$i]);
    $tmp = ($hash << 5) & 0xffffffff;
    $hash = ($tmp - $hash) + $oneChar;
  }
  return $hash;
}

注意: この行$hash &= $hashはノーオペレーションです。それ自体と「AND」された数値は、同じ数値を生成します。

于 2013-07-17T20:40:32.940 に答える