PHP лучший способ для многомерного массива MD5? - PullRequest
108 голосов
/ 12 февраля 2010

Каков наилучший способ создания MD5 (или любого другого хэша) из многомерного массива?

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

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

Ответы [ 13 ]

0 голосов
/ 04 июля 2018

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

Сначала отсортировано с помощью Ksort, а затем выполнено sha1 для json_encode:

ksort($array)
$hash = sha1(json_encode($array) //be mindful of UTF8

пример:

$arr1 = array( 'dealer' => '100', 'direction' => 'ASC', 'dist' => '500', 'limit' => '1', 'zip' => '10601');
ksort($arr1);

$arr2 = array( 'direction' => 'ASC', 'limit' => '1', 'zip' => '10601', 'dealer' => '100', 'dist' => '5000');
ksort($arr2);

var_dump(sha1(json_encode($arr1)));
var_dump(sha1(json_encode($arr2)));

Вывод измененных массивов и хэшей:

string(40) "502c2cbfbe62e47eb0fe96306ecb2e6c7e6d014c"
string(40) "b3319c58edadab3513832ceeb5d68bfce2fb3983"
0 голосов
/ 29 апреля 2016

В настоящее время наиболее одобренный ответ md5(serialize($array)); плохо работает с объектами.

Рассмотрим код:

 $a = array(new \stdClass());
 $b = array(new \stdClass());

Даже если массивы разные (они содержат разные объекты), они имеют одинаковый хэш при использовании md5(serialize($array));. Так что твой хэш бесполезен!

Чтобы избежать этой проблемы, вы можете заменить объекты с результатом spl_object_hash() перед сериализацией. Вы также должны делать это рекурсивно, если ваш массив имеет несколько уровней.

Код ниже также сортирует массивы по ключам, как предположил dotancohen.

function replaceObjectsWithHashes(array $array)
{
    foreach ($array as &$value) {
        if (is_array($value)) {
            $value = $this->replaceObjectsInArrayWithHashes($value);
        } elseif (is_object($value)) {
            $value = spl_object_hash($value);
        }
    }
    ksort($array);
    return $array;
}

Теперь вы можете использовать md5(serialize(replaceObjectsWithHashes($array))).

(Обратите внимание, что массив в PHP имеет тип значения. Поэтому функция replaceObjectsWithHashes НЕ меняет исходный массив.)

0 голосов
/ 09 января 2015

есть несколько ответов, говорящих об использовании json_code,

но json_encode не работает нормально со строкой iso-8859-1, как только появляется специальный символ, строка обрезается.

я бы посоветовал использовать var_export:

md5(var_export($array, true))

не так медленно, как сериализация, не так прослушивается, как json_encode

...