PHP วิธีที่ดีที่สุดในการ MD5 อาร์เรย์หลายมิติ?


120

วิธีที่ดีที่สุดในการสร้าง MD5 (หรือแฮชอื่น ๆ ) ของอาร์เรย์หลายมิติคืออะไร

ฉันสามารถเขียนลูปได้อย่างง่ายดายซึ่งจะข้ามผ่านแต่ละระดับของอาร์เรย์โดยต่อค่าแต่ละค่าเป็นสตริงและเพียงแค่แสดง MD5 บนสตริง

อย่างไรก็ตามสิ่งนี้ดูเหมือนจะยุ่งยากที่สุดและฉันสงสัยว่ามีฟังก์ชั่นขี้ขลาดที่จะใช้อาร์เรย์หลายมิติและแฮช

คำตอบ:


261

(ฟังก์ชัน Copy-n-paste-able ที่ด้านล่าง)

ดังที่ได้กล่าวไว้ก่อนหน้าต่อไปนี้จะใช้งานได้

md5(serialize($array));

อย่างไรก็ตามเป็นที่น่าสังเกตว่า json_encode (แดกดัน) ทำงานได้เร็วขึ้นอย่างเห็นได้ชัด :

md5(json_encode($array));

ในความเป็นจริงการเพิ่มความเร็วเป็นสองเท่าที่นี่เนื่องจาก (1) json_encode เพียงอย่างเดียวทำงานได้เร็วกว่าการทำให้เป็นอนุกรมและ (2) json_encode จะสร้างสตริงที่เล็กกว่าและดังนั้นจึงน้อยกว่าสำหรับ md5 ที่จะจัดการ

แก้ไข:นี่คือหลักฐานที่สนับสนุนการอ้างสิทธิ์นี้:

<?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 เร็วกว่า 250% (2.5x) อย่างต่อเนื่อง (มักจะมากกว่า 300%) - นี่ไม่ใช่ความแตกต่างเล็กน้อย คุณอาจเห็นผลการทดสอบด้วยสคริปต์สดนี้ที่นี่:

ตอนนี้สิ่งหนึ่งที่ควรทราบคืออาร์เรย์ (1,2,3) จะสร้าง MD5 ที่แตกต่างกันเป็นอาร์เรย์ (3,2,1) หากนี่ไม่ใช่สิ่งที่คุณต้องการ ลองใช้รหัสต่อไปนี้:

//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));

แก้ไข:มีคำถามว่าการย้อนกลับคำสั่งจะให้ผลลัพธ์เหมือนกันหรือไม่ ฉันได้ทำอย่างนั้น ( ถูกต้อง ) ที่นี่:

อย่างที่คุณเห็นผลลัพธ์เหมือนกันทุกประการ นี่คือการทดสอบ( แก้ไข ) ที่สร้างขึ้นโดยบุคคลที่เกี่ยวข้องกับ Drupal :

และเพื่อการวัดที่ดีนี่คือฟังก์ชัน / วิธีการที่คุณสามารถคัดลอกและวาง (ทดสอบใน 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));
}

47
ฮ่า ๆ! จริงๆ? ฉันได้รับการโหวตให้ "มากกว่า" การเพิ่มประสิทธิภาพ? ในความเป็นจริงการทำให้อนุกรมของ PHP ช้าลงอย่างมาก ฉันจะอัปเดตคำตอบพร้อมหลักฐาน ...
Nathan JB

19
สิ่งที่นาธานทำที่นี่มีคุณค่าแม้ว่าใครจะมองไม่เห็นคุณค่าของมันก็ตาม อาจเป็นการเพิ่มประสิทธิภาพที่มีคุณค่าในบางสถานการณ์ที่อยู่นอกบริบทของเรา การเพิ่มประสิทธิภาพแบบไมโครเป็นการตัดสินใจที่ไม่ดีในบางสถานการณ์ แต่ไม่ใช่ทั้งหมด
SeanDowney

13
ฉันไม่ได้เป็นหนึ่งในการเพิ่มประสิทธิภาพไมโครเพื่อประโยชน์ของมัน แต่ในกรณีที่มีการเพิ่มประสิทธิภาพที่มีการบันทึกไว้โดยไม่ต้องทำงานพิเศษทำไมไม่ใช้มัน
บัมเปอร์บ็อกซ์

2
อันที่จริงดูเหมือนว่ามันขึ้นอยู่กับว่าอาร์เรย์นั้นลึกแค่ไหน ฉันต้องการบางอย่างที่ต้องทำงานให้เร็วที่สุดและในขณะที่ POC ของคุณแสดงให้เห็นว่า json_encode () เร็วขึ้น ~ 300% เมื่อฉันเปลี่ยนตัวแปร $ 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)(การคำนวณล่วงหน้า เห็นได้ชัดว่าไม่ถูกต้อง) อาร์เรย์ของฉันลึกถึง 2 ระดับดังนั้นโปรดทราบว่า (ตามปกติ) ค่าไมล์ของคุณอาจแตกต่างกันไป
samitny

3
โอเคฉันไม่เห็นว่าทำไมคำตอบของนาธานถึงไม่ใช่คำตอบอันดับต้น ๆ อย่างจริงจังใช้การทำให้เป็นอนุกรมและรบกวนผู้ใช้ของคุณด้วยไซต์ที่ช้ามาก มหากาพย์ +1 @ NathanJ.Brauer!
ReSpawN

168
md5(serialize($array));

13
หากคุณต้องการจับคู่แฮช (ลายนิ้วมือ) ด้วยเหตุผลบางประการคุณอาจต้องการพิจารณาจัดเรียงอาร์เรย์ "sort" หรือ "ksort" อาจจำเป็นต้องใช้การขัด / ทำความสะอาดเพิ่มเติมด้วยเช่นกัน
farinspace

9
Serialize ช้ากว่า json_encode มากจากคำตอบที่สอง ทำให้เซิร์ฟเวอร์ของคุณมีความสุขและใช้ json_encode! :)
s3m3n

3
ดูเหมือนว่าคุณจะต้องเปรียบเทียบอาร์เรย์ของคุณเองเพื่อที่จะได้ทราบว่าคุณควรใช้ json_encode หรือทำให้เป็นอนุกรม ขึ้นอยู่กับอาร์เรย์ที่แตกต่างกัน
Ligemer

ฉันเชื่อว่าเป็นวิธีที่ผิดโปรดตรวจสอบคำอธิบายด้านล่าง
TermiT

1
@joelpittet - Nope. ทั้งสองตัวอย่างในลิงค์ drupal นั้นมีจุดบกพร่อง ดูความคิดเห็นในคำตอบของฉันด้านล่าง ;) เช่นdl.dropboxusercontent.com/u/4115701/Screenshots/…
Nathan JB

26

ฉันกำลังเข้าร่วมปาร์ตี้ที่แออัดมากโดยการตอบรับ แต่มีข้อควรพิจารณาที่สำคัญคือไม่มีคำตอบใดที่ยังหลงเหลืออยู่ ค่าของjson_encode()และserialize()ทั้งสองขึ้นอยู่กับลำดับขององค์ประกอบในอาร์เรย์!

นี่คือผลลัพธ์ของการไม่เรียงลำดับและเรียงลำดับอาร์เรย์ในสองอาร์เรย์ที่มีค่าเหมือนกัน แต่เพิ่มในลำดับที่ต่างกัน (โค้ดที่ด้านล่างของโพสต์) :

    serialize()
1c4f1064ab79e4722f41ab5a8141b210
1ad0f2c7e690c8e3cd5c34f7c9b8573a

    json_encode()
db7178ba34f9271bfca3a05c5dddf502
c9661c0852c2bd0e26ef7951b4ca9e6f

    Sorted serialize()
1c4f1064ab79e4722f41ab5a8141b210
1c4f1064ab79e4722f41ab5a8141b210

    Sorted json_encode()
db7178ba34f9271bfca3a05c5dddf502
db7178ba34f9271bfca3a05c5dddf502

ดังนั้นสองวิธีที่ฉันจะแนะนำให้แฮชอาร์เรย์คือ:

// You will need to write your own deep_ksort(), or see
// my example below

md5(   serialize(deep_ksort($array)) );

md5( json_encode(deep_ksort($array)) );

ทางเลือกของjson_encode()หรือserialize()ควรได้รับการกำหนดโดยการทดสอบกับชนิดของข้อมูลที่คุณกำลังใช้ จากการทดสอบของฉันเองเกี่ยวกับข้อมูลที่เป็นข้อความและตัวเลขล้วนๆหากโค้ดไม่ได้ทำงานแบบวนซ้ำเป็นพัน ๆ ครั้งความแตกต่างก็ไม่คุ้มกับการเปรียบเทียบ ฉันเองใช้json_encode()สำหรับข้อมูลประเภทนั้น

นี่คือรหัสที่ใช้สร้างการทดสอบการเรียงลำดับด้านบน:

$a = array();
$a['aa'] = array( 'aaa'=>'AAA', 'bbb'=>'ooo', 'qqq'=>'fff',);
$a['bb'] = array( 'aaa'=>'BBBB', 'iii'=>'dd',);

$b = array();
$b['aa'] = array( 'aaa'=>'AAA', 'qqq'=>'fff', 'bbb'=>'ooo',);
$b['bb'] = array( 'iii'=>'dd', 'aaa'=>'BBBB',);

echo "    serialize()\n";
echo md5(serialize($a))."\n";
echo md5(serialize($b))."\n";

echo "\n    json_encode()\n";
echo md5(json_encode($a))."\n";
echo md5(json_encode($b))."\n";



$a = deep_ksort($a);
$b = deep_ksort($b);

echo "\n    Sorted serialize()\n";
echo md5(serialize($a))."\n";
echo md5(serialize($b))."\n";

echo "\n    Sorted json_encode()\n";
echo md5(json_encode($a))."\n";
echo md5(json_encode($b))."\n";

การใช้ deep_ksort () อย่างรวดเร็วของฉันเหมาะกับกรณีนี้ แต่ตรวจสอบก่อนใช้กับโครงการของคุณเอง:

/*
* Sort an array by keys, and additionall sort its array values by keys
*
* Does not try to sort an object, but does iterate its properties to
* sort arrays in properties
*/
function deep_ksort($input)
{
    if ( !is_object($input) && !is_array($input) ) {
        return $input;
    }

    foreach ( $input as $k=>$v ) {
        if ( is_object($v) || is_array($v) ) {
            $input[$k] = deep_ksort($v);
        }
    }

    if ( is_array($input) ) {
        ksort($input);
    }

    // Do not sort objects

    return $input;
}

11

คำตอบขึ้นอยู่กับชนิดข้อมูลของค่าอาร์เรย์เป็นอย่างมาก สำหรับสตริงขนาดใหญ่ให้ใช้:

md5(serialize($array));

สำหรับสตริงสั้นและจำนวนเต็มใช้:

md5(json_encode($array));

4 ฟังก์ชั่น PHP สามารถเปลี่ยนอาร์เรย์สตริง: อันดับ () , json_encode () , var_export () , print_r ()

ข้อสังเกต: json_encode ()ฟังก์ชั่นช้าลงขณะประมวลผลอาร์เรย์ Associative ที่มีสตริงเป็นค่า ในกรณีนี้ให้พิจารณาใช้ฟังก์ชันserialize ()

ผลการทดสอบอาร์เรย์หลายมิติที่มี md5-hashes (32 ถ่าน) ในคีย์และค่า:

Test name       Repeats         Result          Performance     
serialize       10000           0.761195 sec    +0.00%
print_r         10000           1.669689 sec    -119.35%
json_encode     10000           1.712214 sec    -124.94%
var_export      10000           1.735023 sec    -127.93%

ผลการทดสอบสำหรับอาร์เรย์หลายมิติที่เป็นตัวเลข:

Test name       Repeats         Result          Performance     
json_encode     10000           1.040612 sec    +0.00%
var_export      10000           1.753170 sec    -68.47%
serialize       10000           1.947791 sec    -87.18%
print_r         10000           9.084989 sec    -773.04%

แหล่งทดสอบอาร์เรย์ที่เกี่ยวข้อง อาร์เรย์เป็นตัวเลขที่มาทดสอบ


คุณช่วยอธิบายได้ไหมว่าสตริงใหญ่และสั้นคืออะไร
AL

1
@AL short strings - สตริงที่มีอักขระน้อยกว่า 25-30 ตัว สตริงขนาดใหญ่ - ทั้งหมดมีมากกว่า 25-30 ตัวอักษร
Alexander Yancharuk

7

นอกเหนือจากคำตอบที่ยอดเยี่ยมของ Brock (+1) แล้วไลบรารีการแฮชที่ดีใด ๆ ยังช่วยให้คุณสามารถอัปเดตแฮชได้ทีละน้อยดังนั้นคุณควรจะสามารถอัปเดตกับแต่ละสตริงตามลำดับได้แทนที่จะต้องสร้างสตริงขนาดใหญ่ขึ้นมา

ดู: hash_update


เป็นที่น่าสังเกตว่าวิธีนี้ไม่มีประสิทธิภาพหากคุณอัปเดตด้วยชิ้นส่วนเล็ก ๆ มันดีสำหรับไฟล์ขนาดใหญ่จำนวนมาก
wrygiel

@wrygiel นั่นไม่เป็นความจริง สำหรับ MD5 การบีบอัดจะทำในบล็อก 64 ไบต์เสมอ (ไม่ว่า "ชิ้นใหญ่" จะมีขนาดเท่าใดก็ตาม) และหากคุณยังไม่ได้เติมบล็อกจะไม่มีการประมวลผลใด ๆ เกิดขึ้นจนกว่าบล็อกจะเต็ม (เมื่อคุณทำแฮชเสร็จสิ้นบล็อกสุดท้ายจะถูกเติมเต็มบล็อกโดยเป็นส่วนหนึ่งของการประมวลผลขั้นสุดท้าย) สำหรับข้อมูลพื้นฐานเพิ่มเติมโปรดอ่านโครงสร้าง Merkle-Damgard (ซึ่ง MD5, SHA-1 และ SHA-2 ล้วนขึ้นอยู่กับ )
Chris Jester-Young

คุณถูก. ฉันรู้สึกผิดอย่างสิ้นเชิงกับความคิดเห็นในไซต์อื่น ๆ
wrygiel

@wrygiel นั่นคือเหตุผลที่คุณต้องจ่ายเงินเพื่อทำวิจัยของคุณเองเมื่อทำตามแนวคิดที่ "พบบนอินเทอร์เน็ต" ;-) พูดอย่างนั้นความคิดเห็นสุดท้ายนั้นง่ายสำหรับฉันที่จะเขียนเพราะฉันใช้ MD5 ตั้งแต่เริ่มต้นเมื่อไม่กี่ปีที่ผ่านมา (เพื่อฝึกฝนทักษะการเขียนโปรแกรม Scheme ของฉัน) ดังนั้นฉันจึงรู้ว่ามันทำงานได้ดีมาก
Chris Jester-Young

นี่คือสิ่งที่ฉันต้องการ บางครั้งการย้ายและคัดลอกข้อมูลขนาดใหญ่ในหน่วยความจำไม่สามารถยอมรับได้ เช่นเดียวกับคำตอบอื่น ๆ ที่ใช้ serialize () เป็นความคิดที่แย่มากในแง่ของประสิทธิภาพ แต่ API นี้ยังคงหายไปหากฉันต้องการแฮชเพียงบางส่วนของสตริงจากค่าชดเชยที่แน่นอน
Jianwu Chen


3

สังเกตว่าserializeและjson_encodeทำงานแตกต่างกันเมื่อพูดถึงอาร์เรย์ตัวเลขที่คีย์ไม่ได้เริ่มต้นที่ 0 หรืออาร์เรย์ที่เชื่อมโยงกัน json_encodeจะจัดเก็บอาร์เรย์ดังกล่าวเป็น an Objectดังนั้นจึงjson_decodeส่งคืน an Objectซึ่งunserializeจะส่งคืนอาร์เรย์ที่มีคีย์เดียวกันทุกประการ


3

ฉันคิดว่านี่อาจเป็นเคล็ดลับที่ดี:

Class hasharray {

    public function array_flat($in,$keys=array(),$out=array()){
        foreach($in as $k => $v){
            $keys[] = $k; 
            if(is_array($v)){
                $out = $this->array_flat($v,$keys,$out);
            }else{
                $out[implode("/",$keys)] = $v;
            }
            array_pop($keys);
        }
        return $out;  
    }

    public function array_hash($in){
        $a = $this->array_flat($in);
        ksort($a);
        return md5(json_encode($a));
    }

}

$h = new hasharray;
echo $h->array_hash($multi_dimensional_array);

2

หมายเหตุสำคัญเกี่ยวกับ serialize()

ฉันไม่แนะนำให้ใช้เป็นส่วนหนึ่งของฟังก์ชันการแฮชเนื่องจากสามารถส่งคืนผลลัพธ์ที่แตกต่างกันสำหรับตัวอย่างต่อไปนี้ ตรวจสอบตัวอย่างด้านล่าง:

ตัวอย่างง่ายๆ:

$a = new \stdClass;
$a->test = 'sample';

$b = new \stdClass;
$b->one = $a;
$b->two = clone $a;

ผลิต

"O:8:"stdClass":2:{s:3:"one";O:8:"stdClass":1:{s:4:"test";s:6:"sample";}s:3:"two";O:8:"stdClass":1:{s:4:"test";s:6:"sample";}}"

แต่รหัสต่อไปนี้:

<?php

$a = new \stdClass;
$a->test = 'sample';

$b = new \stdClass;
$b->one = $a;
$b->two = $a;

เอาท์พุท:

"O:8:"stdClass":2:{s:3:"one";O:8:"stdClass":1:{s:4:"test";s:6:"sample";}s:3:"two";r:2;}"

ดังนั้นแทนที่จะเป็นวัตถุที่สอง php เพียงแค่สร้างลิงค์ "r: 2;" ไปยังอินสแตนซ์แรก เป็นวิธีที่ดีและถูกต้องในการจัดลำดับข้อมูล แต่อาจทำให้เกิดปัญหากับฟังก์ชันแฮชของคุณได้


2
// Convert nested arrays to a simple array
$array = array();
array_walk_recursive($input, function ($a) use (&$array) {
    $array[] = $a;
});

sort($array);

$hash = md5(json_encode($array));

----

These arrays have the same hash:
$arr1 = array(0 => array(1, 2, 3), 1, 2);
$arr2 = array(0 => array(1, 3, 2), 1, 2);

1

มีหลายคำตอบที่บอกให้ใช้ json_code

แต่ json_encode ใช้ไม่ได้กับสตริง iso-8859-1 ทันทีที่มีอักขระพิเศษสตริงจะถูกครอบตัด

ฉันขอแนะนำให้ใช้ var_export:

md5(var_export($array, true))

ไม่ช้าเท่าซีเรียลไลซ์ไม่บั๊กเหมือน json_encode


ไม่เร็วนักตัวเลือกที่ดีที่สุดคือใช้ md4 var_export ก็ช้าเช่นกัน
user956584

0

ขณะนี้คำตอบที่ได้รับการโหวตมากที่สุดใช้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

ฉันไม่เห็นวิธีแก้ปัญหาด้านบนอย่างง่ายดายดังนั้นฉันจึงต้องการให้คำตอบที่ง่ายกว่านี้ สำหรับฉันฉันได้รับคีย์เดียวกันจนกระทั่งฉันใช้ 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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.