(Fungsi dapat menyalin-n-tempel di bagian bawah)
Seperti disebutkan sebelumnya, berikut ini akan berhasil.
md5(serialize($array));
Namun, perlu dicatat bahwa (ironisnya) melakukan json_encode terasa lebih cepat:
md5(json_encode($array));
Faktanya, peningkatan kecepatan dua kali lipat di sini karena (1) json_encode sendiri bekerja lebih cepat daripada serialisasi, dan (2) json_encode menghasilkan string yang lebih kecil dan oleh karena itu lebih sedikit untuk ditangani md5.
Sunting: Berikut adalah bukti untuk mendukung klaim ini:
<?php //this is the array I'm using -- it's multidimensional.
$array = unserialize('a:6:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}i:5;a:5:{i:0;a:0:{}i:1;a:4:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}i:3;a:6:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}i:5;a:5:{i:0;a:0:{}i:1;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:3:{i:0;a:0:{}i:1;a:0:{}i:2;a:0:{}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}}}}i:2;s:5:"hello";i:3;a:2:{i:0;a:0:{}i:1;a:0:{}}i:4;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:1:{i:0;a:0:{}}}}}}}}}');
//The serialize test
$b4_s = microtime(1);
for ($i=0;$i<10000;$i++) {
$serial = md5(serialize($array));
}
echo 'serialize() w/ md5() took: '.($sTime = microtime(1)-$b4_s).' sec<br/>';
//The json test
$b4_j = microtime(1);
for ($i=0;$i<10000;$i++) {
$serial = md5(json_encode($array));
}
echo 'json_encode() w/ md5() took: '.($jTime = microtime(1)-$b4_j).' sec<br/><br/>';
echo 'json_encode is <strong>'.( round(($sTime/$jTime)*100,1) ).'%</strong> faster with a difference of <strong>'.($sTime-$jTime).' seconds</strong>';
JSON_ENCODE secara konsisten lebih dari 250% (2,5x) lebih cepat (seringkali lebih dari 300%) - ini bukanlah perbedaan yang sepele. Anda dapat melihat hasil pengujian dengan skrip langsung ini di sini:
Sekarang, satu hal yang perlu diperhatikan adalah array (1,2,3) akan menghasilkan MD5 yang berbeda sebagai array (3,2,1). Jika ini BUKAN yang Anda inginkan. Coba kode berikut:
//Optionally make a copy of the array (if you want to preserve the original order)
$original = $array;
array_multisort($array);
$hash = md5(json_encode($array));
Sunting: Ada beberapa pertanyaan, apakah membalikkan pesanan akan menghasilkan hasil yang sama. Jadi, saya telah melakukannya ( dengan benar ) di sini:
Seperti yang Anda lihat, hasilnya persis sama. Inilah tes ( dikoreksi ) yang awalnya dibuat oleh seseorang yang terkait dengan Drupal :
Dan untuk ukuran yang baik, berikut adalah fungsi / metode yang dapat Anda salin dan tempel (diuji di 5.3.3-1ubuntu9.5):
function array_md5(Array $array) {
//since we're inside a function (which uses a copied array, not
//a referenced array), you shouldn't need to copy the array
array_multisort($array);
return md5(json_encode($array));
}
serialize() w/ md5() took: 0.27773594856262 sec
json_encode() w/ md5() took: 0.34809803962708 sec
json_encode is (79.8%) faster with a difference of (-0.070362091064453 seconds)
(perhitungan present jelas salah). Array saya memiliki kedalaman hingga 2 level, jadi ingatlah bahwa (seperti biasa) jarak tempuh Anda mungkin berbeda.sumber
Saya bergabung dengan pesta yang sangat ramai dengan menjawab, tetapi ada pertimbangan penting bahwa tidak ada jawaban yang masih ada yang alamat. Nilai
json_encode()
danserialize()
keduanya bergantung pada urutan elemen dalam larik!Berikut adalah hasil dari tidak mengurutkan dan mengurutkan array, pada dua array dengan nilai yang identik tetapi ditambahkan dalam urutan yang berbeda (kode di bagian bawah posting) :
Oleh karena itu, dua metode yang saya rekomendasikan untuk melakukan hash sebuah array adalah:
Pilihan
json_encode()
atauserialize()
harus ditentukan dengan menguji jenis data yang Anda gunakan . Dengan pengujian saya sendiri pada data tekstual dan numerik murni, jika kode tidak menjalankan loop ketat ribuan kali maka perbedaannya bahkan tidak layak untuk dijadikan tolok ukur. Saya pribadi menggunakanjson_encode()
untuk jenis data itu.Berikut adalah kode yang digunakan untuk menghasilkan tes pengurutan di atas:
Implementasi deep_ksort () saya yang cepat, cocok dengan kasus ini, tetapi periksa sebelum digunakan pada proyek Anda sendiri:
sumber
Jawabannya sangat tergantung pada tipe data nilai array. Untuk string besar, gunakan:
Untuk string pendek dan bilangan bulat, gunakan:
4 fungsi PHP bawaan dapat mengubah array menjadi string: serialize () , json_encode () , var_export () , print_r () .
Hasil tes untuk array multi-dimensi dengan md5-hashes (32 char) pada kunci dan nilai:
Hasil tes untuk larik multi-dimensi numerik:
Sumber pengujian array asosiatif . Sumber pengujian larik numerik .
sumber
Selain dari jawaban Brock yang sangat baik (+1), pustaka hashing yang layak memungkinkan Anda memperbarui hash secara bertahap, jadi Anda harus dapat memperbarui setiap string secara berurutan, alih-alih harus membangun satu string raksasa.
Lihat:
hash_update
sumber
Akan berfungsi, tetapi hash akan berubah tergantung pada urutan array (itu mungkin tidak masalah).
sumber
Perhatikan bahwa
serialize
danjson_encode
bertindak secara berbeda ketika datang ke array numerik di mana kuncinya tidak dimulai dari 0, atau array asosiatif.json_encode
akan menyimpan array seperti ituObject
, jadijson_decode
mengembalikan sebuahObject
, di manaunserialize
akan mengembalikan array dengan kunci yang sama persis.sumber
Saya pikir ini bisa menjadi tip yang bagus:
sumber
Catatan penting tentang
serialize()
Saya tidak menyarankan untuk menggunakannya sebagai bagian dari fungsi hashing karena dapat mengembalikan hasil yang berbeda untuk contoh berikut. Lihat contoh di bawah ini:
Contoh sederhana:
Menghasilkan
Tetapi kode berikut:
Keluaran:
Jadi, alih-alih objek kedua php cukup buat tautan "r: 2;" ke contoh pertama. Ini pasti cara yang baik dan benar untuk membuat serial data, tetapi itu dapat menyebabkan masalah dengan fungsi hashing Anda.
sumber
sumber
ada beberapa jawaban yang mengatakan untuk menggunakan json_code,
tetapi json_encode tidak berfungsi dengan baik dengan string iso-8859-1, segera setelah ada karakter khusus, string tersebut dipotong.
saya akan menyarankan untuk menggunakan var_export:
tidak selambat serialize, tidak disadap seperti json_encode
sumber
Saat ini, jawaban yang paling banyak dipilih
md5(serialize($array));
tidak berfungsi dengan baik dengan objek.Pertimbangkan kode:
Meskipun array berbeda (berisi objek yang berbeda), mereka memiliki hash yang sama saat digunakan
md5(serialize($array));
. Jadi hash Anda tidak berguna!Untuk menghindari masalah tersebut, Anda dapat mengganti objek dengan hasil
spl_object_hash()
sebelum serialisasi. Anda juga harus melakukannya secara rekursif jika array Anda memiliki beberapa level.Kode di bawah ini juga mengurutkan array berdasarkan kunci, seperti yang disarankan oleh Dotancohen.
Sekarang Anda bisa menggunakan
md5(serialize(replaceObjectsWithHashes($array)))
.(Perhatikan bahwa array dalam PHP adalah tipe nilai. Jadi
replaceObjectsWithHashes
fungsi JANGAN mengubah array asli.)sumber
Saya tidak melihat solusi dengan mudah di atas, jadi saya ingin memberikan jawaban yang lebih sederhana. Bagi saya, saya mendapatkan kunci yang sama sampai saya menggunakan ksort (semacam kunci):
Diurutkan terlebih dahulu dengan Ksort, lalu lakukan sha1 di json_encode:
contoh:
Output dari array dan hash yang diubah:
sumber