Как создать уникальную строку из массива php - PullRequest
5 голосов
/ 25 февраля 2011

Мне нужна уникальная строка из массива, чтобы я мог сказать, когда она меняется, не измеряя входные данные этого массива. Я пытаюсь понять, является ли вычислительно эффективным вычисление значения, а не добавление кода для поиска изменений в массиве. Сам массив может иметь различные значения, и для дальнейшей проверки я не хочу пытаться измерить, были ли новые значения добавлены в массив, я бы предпочел просто создать некоторую строку или хэш, который изменится, если сам массив изменения.

Так, например:

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

Если бы я использовал md5(http_build_query($a)), возможно, с добавленным ksort, чтобы подтвердить, что порядок ключей не изменился, это может привести к уникальной строке, которую я могу использовать для сравнения с другим запуском приложения с оценить, изменился ли массив.

Я ищу альтернативные, возможно более быстрые или более элегантные решения для этого.

Ответы [ 4 ]

7 голосов
/ 25 февраля 2011

Я использую md5(serialize($array)) для этого.Это лучше, потому что работает для многомерных массивов.

2 голосов
/ 25 февраля 2011

Спасибо за все идеи, ребята.

Я перепробовал их все, кроме 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();
2 голосов
/ 25 февраля 2011

PHP имеет функцию array_diff () , не знаю, нужна ли она вам.

В противном случае вы можете в конечном итоге использовать возможность инкрементного хэширования, предлагаемую php: http://www.php.net/manual/en/function.hash-init.php, перебирая все значения массива и добавляя их в инкрементный хеш.

1 голос
/ 25 февраля 2011

Вы всегда можете просто сделать

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

Теоретически, это должно обнаружить изменения размера массива, данных или порядка.

Конечно, вы можете использовать любой хеш, какой пожелаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...