【问题标题】:How to produce a unique string from a php array如何从 php 数组中生成唯一的字符串
【发布时间】:2011-07-03 23:44:44
【问题描述】:

我需要一个数组中的唯一字符串,这样我就可以知道它何时发生变化,而无需测量该数组的输入。我正在尝试确定计算值是否在计算上是有效的,而不是添加代码来查找数组中的变化。数组本身可以有多种值,为了将来的验证,我不想尝试测量新值是否已添加到数组中,我宁愿创建一些字符串或哈希值,如果数组本身会改变变化。

例如:

$a = Array(
'var1' => 1,
'var2' => 2,
'var3' => 3,
);

如果我要使用 md5(http_build_query($a)) 或者添加 ksort 来确认键的顺序没有改变,这可能会产生一个唯一的字符串,我可以用它来与应用程序的另一次运行进行比较评估数组是否发生了变化。

我正在寻找一种替代的、可能更快或更优雅的解决方案。

【问题讨论】:

  • 我认为 array_diff 不会处理检查键顺序是否已更改。您可以对数组进行 json_encode 并对其进行哈希处理。可能要检查 json_encode 和 http_build_query 的性能。

标签: php arrays hash


【解决方案1】:

我为此使用md5(serialize($array))。它更好,因为适用于多维数组。

【讨论】:

    【解决方案2】:

    感谢所有想法的家伙。

    除了我的服务器没有安装的 sha-256 之外,我已经尝试了所有这些。

    结果如下:

    Average (http_build_query): 1.3954045954045E-5
    Average (diff): 0.00011533766233766
    Average (serialize): 1.7588411588412E-5
    Average (md5): 1.6036963036966E-5
    Average (implode-haval160,4): 1.5349650349649E-5
    

    这是运行 1000 次并平均结果。刷新几次后,我可以看出 http_build_query 是最快的。我想我的下一个问题是,是否有人能想到使用这种方法的任何陷阱?

    谢谢

    这是我的代码:

    class a {
    
        static $input;
    
        function test() {
            $start = null;
            $s = $e = $d = $g = $h = $i = $k = array();
            self::$input = array();
    
            for ($x = 0; $x <= 30; $x++) {
                self::$input['variable_' . $x] = rand();
            }
    
            for ($x = 0; $x <= 1000; $x++) {
                $start = microtime();
    
                $c = http_build_query(self::$input);
                ($c == $c);
    
                $s[] = microtime() - $start;
            }
    
            for ($x = 0; $x <= 1000; $x++) {
                $start = microtime();
    
                $c = md5(http_build_query(self::$input));
                ($c == $c);
    
                $e[] = microtime() - $start;
            }
    
            for ($x = 0; $x <= 1000; $x++) {
                $start = microtime();
    
                $c = array_diff(self::$input, self::$input);
    
                $d[] = microtime() - $start;
            }
            for ($x = 0; $x <= 1000; $x++) {
                $start = microtime();
    
                $c = serialize(self::$input);
                ($c == $c);
    
                $g[] = microtime() - $start;
            }
    
            for ($x = 0; $x <= 1000; $x++) {
                $start = microtime();
    
                $c =  hash("haval160,4", implode(',',self::$input));
                ($c == $c);
    
                $h[] = microtime() - $start;
            }
            echo "<pre>";
    
    //print_r($s);
            echo "Average (http_build_query): " . array_sum($s) / count($s) . "<br>";
            echo "Average (diff): " . array_sum($d) / count($d) . "<br>";
            echo "Average (serialize): " . array_sum($g) / count($g) . "<br>";
            echo "Average (md5): " . array_sum($e) / count($e). "<br>";
            echo "Average (implode-haval160,4): " . array_sum($h) / count($h);
        }
    
    }
    
    a::test();
    

    【讨论】:

    • 该死的天才array_diff(self::$input, self::$input);
    • 在实际使用中很好,对于这个应用程序,大部分时间它都是匹配的,所以我决定我想计算识别匹配而不是识别不匹配所需的时间。如果我是正确的,识别不匹配将花费更少的时间,因为它必须迭代并检查每个键。它只会停止检查它是否发现了差异,但它没有,所以按照这个逻辑希望这意味着我通过比较完全相同的变量来更加保守
    【解决方案3】:

    PHP有一个array_diff()函数,不知道对你有没有用。

    否则,您最终可以使用 php 提供的增量散列可能性:http://www.php.net/manual/en/function.hash-init.php 通过迭代数组的每个值并将它们添加到增量散列中。

    【讨论】:

      【解决方案4】:

      你总是可以这样做

      $str = implode(",", $a);
      $check = hash("sha-256", $str);
      

      理论上,这应该会检测到数组大小、数据或顺序的变化。

      当然,你可以使用任何你想要的哈希值。

      【讨论】:

      • 其实delphist可能是对的,如果不知道数组的维度,serialize()可能会更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      相关资源
      最近更新 更多