ทำไม XOR ถึงเป็นวิธีเริ่มต้นในการรวมแฮช


145

สมมติว่าคุณมีสอง hashes H(A)และH(B)และคุณต้องการที่จะรวมพวกเขา ผมเคยอ่านว่าเป็นวิธีที่ดีที่จะรวมทั้งสอง hashes คือการให้พวกเขาเช่นXORXOR( H(A), H(B) )

คำอธิบายที่ดีที่สุดที่ฉันพบถูกสัมผัสสั้น ๆ ที่นี่ในแนวทางฟังก์ชั่นแฮช :

แฮคเกอร์ตัวเลขสองตัวที่มีการแจกแจงแบบสุ่มอย่างคร่าวๆส่งผลให้ตัวเลขอีกตัวยังคงมีการกระจายแบบสุ่ม * แต่ตอนนี้ขึ้นอยู่กับค่าสองค่า
...
* ที่แต่ละบิตของสองตัวเลขที่จะรวมกัน 0 จะถูกส่งออกถ้าทั้งสองบิตมีค่าเท่ากันหรือ 1 ในคำอื่น ๆ 50% ของชุดค่าผสมจะมีการส่งออก 1 ดังนั้นถ้าบิตอินพุตสองตัวแต่ละตัวมีโอกาสประมาณ 50-50 ที่จะเป็น 0 หรือ 1 ดังนั้นบิตเอาต์พุตก็เช่นกัน

คุณสามารถอธิบายสัญชาตญาณและ / หรือคณิตศาสตร์ได้ไหมว่าทำไมแฮคเกอร์ถึงควรเป็นปฏิบัติการเริ่มต้นสำหรับการรวมฟังก์ชั่นแฮช (แทนที่จะเป็น OR หรือ AND เป็นต้น)


20
ฉันคิดว่าคุณเพิ่งทำ;)
Massa

22
โปรดทราบว่าแฮคเกอร์อาจจะใช่หรือไม่ใช่วิธีที่ดีในการ "รวม" แฮชทั้งนี้ขึ้นอยู่กับสิ่งที่คุณต้องการใน "ชุดค่าผสม" แฮคเกอร์คือ: XOR (H (A), H (B)) เท่ากับ XOR (H (B), H (A)) ซึ่งหมายความว่า XOR ไม่ใช่วิธีที่เหมาะสมในการสร้างแฮชชนิดหนึ่งของค่าลำดับที่เรียงลำดับเนื่องจากมันไม่ได้จับลำดับ
โทมัส Pornin

6
นอกเหนือจากปัญหาเกี่ยวกับการสั่งซื้อ (ความคิดเห็นด้านบน) ยังมีปัญหากับค่าที่เท่ากัน XOR (H (1), H (1)) = 0 (สำหรับฟังก์ชันใด ๆ H), XOR (H (2), H (2)) = 0 และอื่น ๆ สำหรับ N: XOR (H (N), H (N)) = 0 ค่าที่เท่ากันเกิดขึ้นบ่อยครั้งในแอปจริงหมายความว่าผลลัพธ์ของ XOR จะเป็น 0 บ่อยเกินไปที่จะถือว่าเป็นแฮชที่ดี
Andrei Galatyn

คุณใช้อะไรในการเรียงลำดับของค่า สมมติว่าฉันต้องการสร้างแฮชของการประทับเวลาหรือดัชนี (MSB มีความสำคัญน้อยกว่า LSB) ขออภัยถ้าเธรดนี้มีอายุ 1 ปี
Alexis

คำตอบ:


120

สมมติว่าสุ่มสม่ำเสมอ (1 บิต) ปัจจัยการผลิตและการทำงานการกระจายการส่งออกเป็น 75% 0และ 125% ตรงกันข้ามหรือเป็น 25% 0และ 175%

ฟังก์ชัน XOR คือ 50% 0และ 50% 1ดังนั้นจึงเป็นการดีสำหรับการรวมการแจกแจงความน่าจะเป็นแบบเดียวกัน

สิ่งนี้สามารถเห็นได้โดยการเขียนตารางความจริง:

 a | b | a AND b
---+---+--------
 0 | 0 |    0
 0 | 1 |    0
 1 | 0 |    0
 1 | 1 |    1

 a | b | a OR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    1

 a | b | a XOR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    0

การออกกำลังกาย: มีฟังก์ชันลอจิคัลกี่ตัวของอินพุต 1 บิตสองตัวaและbมีการกระจายเอาต์พุตที่สม่ำเสมอ เหตุใดแฮคเกอร์จึงเหมาะสมที่สุดสำหรับวัตถุประสงค์ที่ระบุไว้ในคำถามของคุณ


24
ตอบการฝึกหัด: จากการดำเนินการ XXX b ที่แตกต่างกัน 16 แบบ(0, a & b, a > b, a, a < b, b, a % b, a | b, !a & !b, a == b, !b, a >= b, !a, a <= b, !a | !b, 1)ต่อไปนี้มีการแจกแจง 50% -50% ของ 0s และ 1s โดยสมมติว่า a และ b มีการแจกแจง 50% -50% ของ 0s และ 1s: a, b, !a, !b, a % b, a == bคือตรงกันข้าม ของแฮคเกอร์ (EQUIV) จะได้รับใช้เช่นกัน ...
มาสซ่า

7
เกร็กนี่คือคำตอบที่ยอดเยี่ยม หลอดไฟเดินต่อไปหลังจากฉันเห็นคำตอบเดิมของคุณและเขียนตารางความจริงของฉันเอง ฉันพิจารณาคำตอบของ @ Massa ว่ามีการดำเนินงานที่เหมาะสม 6 วิธีในการรักษาการกระจายสินค้าอย่างไร และในขณะที่a, b, !a, !bจะมีการกระจายเช่นเดียวกับอินพุตของพวกเขาคุณสูญเสียเอนโทรปีของอินพุตอื่น นั่นคือ XOR เหมาะสมที่สุดสำหรับวัตถุประสงค์ในการรวมแฮชเพราะเราต้องการรวบรวมเอนโทรปีจาก a และ b
Nate Murray

1
นี่คือกระดาษที่อธิบายว่าการรวมแฮชอย่างแน่นหนาซึ่งแต่ละฟังก์ชั่นถูกเรียกใช้เพียงครั้งเดียวไม่สามารถทำได้โดยไม่ส่งบิตน้อยกว่าผลรวมของจำนวนบิตในแต่ละค่าแฮช สิ่งนี้แนะนำว่าคำตอบนี้ไม่ถูกต้อง
Tamás Szelei

3
@Massa ฉันไม่เคยเห็น% ใช้สำหรับ XOR หรือไม่เท่ากัน
Buge

7
เมื่อYakk ชี้ให้เห็น XOR อาจเป็นอันตรายได้ในขณะที่มันสร้างศูนย์สำหรับค่าที่เหมือนกัน นี่หมายถึง(a,a)และ(b,b)ทั้งคู่ผลิตศูนย์ซึ่งในหลาย ๆ กรณี (ส่วนใหญ่?) เพิ่มโอกาสการชนในโครงสร้างข้อมูลแบบแฮชอย่างมาก
Drew Noakes

170

xorเป็นฟังก์ชั่นเริ่มต้นที่เป็นอันตรายที่จะใช้เมื่อทำการแฮช มันดีกว่าandและorแต่ก็ไม่ได้พูดอะไรมาก

xorมีความสมมาตรดังนั้นลำดับขององค์ประกอบจึงหายไป ดังนั้นพระทัยกัญชารวมเช่นเดียวกับ"bad""dab"

xor จับคู่ค่าที่เหมือนกันของคู่กับศูนย์และคุณควรหลีกเลี่ยงการจับคู่ค่า "ทั่วไป" กับศูนย์:

ดังนั้น(a,a)แมปถึง 0 และ(b,b)ได้รับการแมปเป็น 0 เนื่องจากคู่เหล่านี้มักพบบ่อยกว่าการสุ่มอาจบอกเป็นนัยว่าคุณจะพบกับการชนจำนวนมากที่ศูนย์เกินกว่าที่คุณควรจะเป็น

ด้วยปัญหาทั้งสองนี้xorกลายเป็น combiner แฮชที่ดูดีครึ่งบนพื้นผิว แต่ไม่ใช่หลังจากการตรวจสอบเพิ่มเติม

บนฮาร์ดแวร์ที่ทันสมัยการเพิ่มมักจะเร็วเท่าxor(อาจใช้พลังงานมากขึ้นเพื่อดึงสิ่งนี้ออกมายอมรับ) ตารางความจริงของการเพิ่มคล้ายกับxorในบิตของคำถาม แต่ยังส่งบิตไปยังบิตถัดไปเมื่อค่าทั้งสองเป็น 1 ซึ่งหมายความว่ามันลบข้อมูลน้อยลง

ดังนั้นhash(a) + hash(b)จะดีกว่าhash(a) xor hash(b)ถ้าa==bผลลัพธ์ออกมาเป็นhash(a)<<10

เรื่องนี้ยังคงสมมาตร ดังนั้น"bad"และ"dab"ได้รับผลลัพธ์เดียวกันยังคงมีปัญหา เราสามารถแบ่งสมมาตรนี้ด้วยราคาที่ไม่แพง:

hash(a)<<1 + hash(a) + hash(b)

hash(a)*3 + hash(b)อาคา (คำนวณhash(a)หนึ่งครั้งและแนะนำให้เก็บถ้าคุณใช้วิธีเปลี่ยนกะ) ใด ๆ คงแปลกแทนที่จะ3bijectively แผนที่จะเป็น " kบิต" จำนวนเต็มไม่ได้ลงนามกับตัวเองเป็นแผนที่ในจำนวนเต็มไม่ได้ลงนามเป็นแบบโมดูโลคณิตศาสตร์2^kสำหรับบางคนkและคงแปลก ๆ 2^kค่อนข้างสำคัญในการ

สำหรับรุ่นที่ยิ่งกว่านั้นเราสามารถตรวจสอบboost::hash_combineได้ซึ่งมีประสิทธิภาพ:

size_t hash_combine( size_t lhs, size_t rhs ) {
  lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
  return lhs;
}

ที่นี่เราเพิ่มบางเวอร์ชั่นที่seedมีการเปลี่ยนแปลงด้วยค่าคงที่ (ซึ่งโดยทั่วไปจะเป็นแบบสุ่ม0และ1s - โดยเฉพาะอย่างยิ่งมันเป็นสิ่งที่ตรงกันข้ามกับอัตราส่วนทองคำเป็นเศษส่วนจุดคงที่ 32 บิต) ด้วยการเพิ่มและ xor แบ่งนี้สมมาตรและแนะนำบางคน "เสียง" ถ้าค่าแฮชที่เข้ามาไม่ดี (เช่นจินตนาการทุก hashes ส่วนประกอบ 0 - จับดังกล่าวข้างต้นได้ดีสร้าง smear ของ1และ0. s หลังจากแต่ละรวมของฉันไร้เดียงสา3*hash(a)+hash(b)เพียง outputs 0ใน กรณีนั้น)

(สำหรับผู้ที่ไม่คุ้นเคยกับ C / C ++ a size_tคือค่าจำนวนเต็มที่ไม่ได้ลงนามซึ่งใหญ่พอที่จะอธิบายขนาดของวัตถุใด ๆ ในหน่วยความจำบนระบบ 64 บิตโดยปกติจะเป็นจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อบนระบบ 32 บิต เป็นจำนวนเต็ม 32 บิตที่ไม่ได้ลงชื่อ)


คำตอบที่ดี Yakk อัลกอริทึมนี้ใช้งานได้ดีกับทั้งระบบ 32 บิตและ 64 บิตหรือไม่ ขอบคุณ
เดฟ

1
@dave เพิ่มบิตให้0x9e3779b9มากขึ้น
Yakk - Adam Nevraumont

10
ตกลงเพื่อให้เสร็จสมบูรณ์ ... นี่คือค่าคงที่ 64 บิตที่มีความแม่นยำเต็มรูปแบบ (คำนวณด้วยความยาวคู่และยาวที่ไม่ได้ลงชื่อ): 0x9e3779b97f4a7c16 ที่น่าสนใจก็คือยัง ทำการคำนวณเดียวกันซ้ำอีกครั้งโดยใช้ PI แทนอัตราส่วนทองคำสร้าง: 0x517cc1b727220a95 ซึ่งเป็นเลขคี่แทนที่จะเป็นคู่ดังนั้นอาจจะ "สำคัญกว่า" มากกว่าค่าคงที่อื่น ฉันใช้: std :: cout << std :: hex << (ยาวที่ไม่ได้ลงชื่อ) ((1.0L / 3.14159265358979323846264338327950288419716939937510L) * (powl (2.0L, 64.0L))) << std; ด้วย cout.precision (numeric_limits <long double> :: max_digits10); ขอบคุณอีกครั้ง Yakk
เดฟ

2
@Dave กฎอัตราส่วนทองคำผกผันสำหรับกรณีเหล่านี้เป็นเลขคี่แรกเท่ากับหรือใหญ่กว่าการคำนวณที่คุณทำ ดังนั้นเพียงแค่เพิ่ม 1 มันเป็นจำนวนที่สำคัญเพราะลำดับของอัตราส่วน N *, mod ขนาดสูงสุด (2 ^ 64 ที่นี่) วางค่าต่อไปในลำดับที่ตรงกับอัตราส่วนนั้นในช่วงกลางของ 'ช่องว่าง' ที่ใหญ่ที่สุดใน หมายเลข ค้นหาเว็บ "Fibonacci hashing" เพื่อรับข้อมูลเพิ่มเติม
Scott Carey

1
@Dave จำนวนที่เหมาะสมจะเป็น 0.9E3779B97F4A7C15F39 ... ดูการเชื่อมโยง คุณอาจต้องทนทุกข์ทรมานจากกฎรอบต่อเนื่อง (ซึ่งดีสำหรับนักบัญชี) หรือเพียงแค่ถ้าคุณเริ่มต้นด้วยค่าคงที่ sqrt (5) ตามตัวอักษรเมื่อคุณลบ 1 คุณจะลบบิตคำสั่งสูง บิตต้องหายไป
โยกย้าย

29

ทั้งๆที่มีคุณสมบัติการผสมบิตที่มีประโยชน์ XOR ไม่ใช่วิธีที่ดีในการรวมแฮชเนื่องจากการสับเปลี่ยน พิจารณาสิ่งที่จะเกิดขึ้นหากคุณเก็บพีชคณิตของ {1, 2, …, 10} ไว้ในตารางแฮชของ tuples 10 อัน

ทางเลือกที่ดีกว่าคือm * H(A) + H(B)ที่mคือเลขคี่ขนาดใหญ่

เครดิต: combiner ด้านบนเป็นเคล็ดลับจาก Bob Jenkins


2
บางครั้งการสับเปลี่ยนกำลังเป็นสิ่งที่ดี แต่ xor เป็นตัวเลือกที่มีหมัดแม้กระทั่งเพราะรายการจับคู่ทั้งหมดจะถูกแฮชเป็นศูนย์ ผลรวมเลขคณิตดีกว่า การแฮชของรายการจับคู่คู่หนึ่งจะเก็บข้อมูลที่มีประโยชน์เพียง 31 บิตมากกว่า 32 แต่มันก็ยังดีกว่าการรักษาศูนย์เอาไว้ อีกทางเลือกหนึ่งคือการคำนวณผลรวมเลขคณิตเป็น a longและรวมส่วนบนเข้าด้วยส่วนล่าง
supercat

1
m = 3เป็นทางเลือกที่ดีและรวดเร็วมากในหลาย ๆ ระบบ โปรดทราบว่าสำหรับการmคูณจำนวนเต็มแปลก ๆคือโมดูโลห2^32รือ2^64กลับกันได้ดังนั้นคุณจะไม่สูญเสียบิตใด ๆ
StefanKarpinski

จะเกิดอะไรขึ้นเมื่อคุณไปไกลกว่า MaxInt?
ก่อกวน

2
แทนที่จะเป็นเลขคี่ใดควรเลือกนายก
TermoTux

2
@Infinum ที่ไม่จำเป็นเมื่อรวมแฮช
Marcelo Cantos

17

Xor อาจเป็นวิธี "เริ่มต้น" ในการรวมแฮช แต่คำตอบของ Greg Hewgill ยังแสดงให้เห็นว่าทำไมมันถึงมีข้อผิดพลาด: แฮคเกอร์ของค่าแฮชที่เหมือนกันสองค่าเป็นศูนย์ ในชีวิตจริงมีแฮชเหมือนกันที่พบบ่อยกว่าที่คาดไว้ จากนั้นคุณอาจพบว่าในกรณีมุมเหล่านี้ (ไม่บ่อยนัก) การแฮชรวมที่เกิดขึ้นจะเหมือนกันเสมอ (ศูนย์) การชนของแฮชจะบ่อยกว่าที่คุณคาดไว้มาก

ในตัวอย่างที่วางแผนไว้คุณอาจรวมรหัสผ่านที่แฮชของผู้ใช้จากเว็บไซต์ต่างๆที่คุณจัดการ น่าเสียดายที่มีผู้ใช้จำนวนมากนำรหัสผ่านมาใช้ซ้ำและสัดส่วนของแฮชที่เกิดขึ้นนั้นเป็นศูนย์!


ฉันหวังว่าตัวอย่างที่วางแผนไว้จะไม่เกิดขึ้นรหัสผ่านควรได้รับการใส่เกลือ
user60561

8

มีบางสิ่งที่ฉันต้องการชี้ให้เห็นอย่างชัดเจนสำหรับคนอื่นที่พบหน้านี้ และและหรือ จำกัด เอาต์พุตเช่น BlueRaja - Danny Pflughoe พยายามที่จะชี้ให้เห็น แต่สามารถกำหนดได้ดีกว่า:

ก่อนอื่นฉันต้องการนิยามฟังก์ชั่นง่าย ๆ สองอย่างที่ฉันจะใช้อธิบาย: Min () และ Max ()

ต่ำสุด (A, B) จะคืนค่าที่เล็กกว่าระหว่าง A และ B ตัวอย่างเช่น: Min (1, 5) ส่งคืน 1

Max (A, B) จะคืนค่าที่ใหญ่กว่าระหว่าง A และ B ตัวอย่างเช่น: Max (1, 5) ส่งคืน 5

หากคุณได้รับ: C = A AND B

จากนั้นคุณจะพบว่าC <= Min(A, B)เรารู้สิ่งนี้เพราะไม่มีสิ่งใดที่คุณสามารถทำได้และด้วย 0 บิตของ A หรือ B เพื่อทำให้เป็น 1s ดังนั้นทุก ๆ ศูนย์บิตจะมีค่าเป็นศูนย์บิตและทุก ๆ หนึ่งบิตมีโอกาสที่จะกลายเป็นศูนย์บิต (และทำให้มีค่าน้อยกว่า)

ด้วย: C = A OR B

ตรงกันข้ามคือจริง: C >= Max(A, B)ด้วยสิ่งนี้เราจะเห็นข้อพิสูจน์ของฟังก์ชัน AND บิตใดก็ตามที่มีอยู่แล้วหนึ่งอันไม่สามารถถูก ORed ให้เป็นศูนย์ได้ดังนั้นจึงยังคงอยู่หนึ่งบิต แต่ทุก ๆ บิตศูนย์มีโอกาสที่จะกลายเป็นหนึ่งและทำให้มีจำนวนมากขึ้น

นี่หมายความว่าสถานะของอินพุตใช้ข้อ จำกัด กับเอาต์พุต ถ้าคุณและทุกอย่างที่มี 90 คุณรู้ว่าผลลัพธ์จะเท่ากับหรือน้อยกว่า 90 โดยไม่คำนึงถึงค่าอื่น ๆ

สำหรับ XOR ไม่มีข้อ จำกัด โดยนัยตามอินพุต มีกรณีพิเศษที่คุณสามารถพบว่าถ้าคุณแฮคเกอร์ที่มี 255 มากกว่าที่คุณได้รับการผกผัน แต่ไบต์ที่เป็นไปได้ใด ๆ สามารถส่งออกจากที่ ทุกบิตมีโอกาสเปลี่ยนสถานะขึ้นอยู่กับบิตเดียวกันในตัวถูกดำเนินการอื่น


6
หนึ่งอาจกล่าวได้ว่าORเป็นสูงสุดค่าที่เหมาะสมและANDเป็นค่าที่เหมาะสมนาที
Paŭlo Ebermann

เปาโลเอเบอร์มันน์กล่าวไว้เป็นอย่างดี ดีใจที่ได้พบคุณที่นี่เช่นเดียวกับ Crypto.SE!
Corey Ogburn

ฉันสร้างตัวกรองซึ่งรวมทุกอย่างไว้ด้วยการเข้ารหัสที่ติดแท็กฉันยังเปลี่ยนเป็นคำถามเก่า วิธีนี้ฉันพบคำตอบของคุณที่นี่
Paŭlo Ebermann

3

หากคุณXORอินพุตแบบสุ่มที่มีอินพุตแบบเอนเอียงเอาต์พุตจะเป็นแบบสุ่ม เช่นเดียวกับที่ไม่เป็นความจริงสำหรับหรือAND ORตัวอย่าง:

00101001 XOR 00000000 = 00101001
00101001 และ 00000000 = 00000000
00101001 หรือ 11111111 = 11111111

ดังที่ @Greg Hewgill กล่าวถึงแม้ว่าทั้งสองอินพุตจะสุ่มใช้ANDหรือORส่งผลให้เอาต์พุตแบบเอนเอียง

เหตุผลที่เราใช้XORกับบางสิ่งที่ซับซ้อนกว่านั้นก็คือไม่จำเป็นต้องใช้ XORงานได้อย่างสมบูรณ์แบบและโง่อย่างรวดเร็ว


1

ครอบคลุม 2 คอลัมน์ด้านซ้ายและพยายามหาว่าอินพุตใช้เพียงแค่เอาต์พุต

 a | b | a AND b
---+---+--------
 0 | 0 |    0
 0 | 1 |    0
 1 | 0 |    0
 1 | 1 |    1

เมื่อคุณเห็น 1 บิตคุณควรหาว่าทั้งสองอินพุตเป็น 1

ตอนนี้ทำเช่นเดียวกันสำหรับ XOR

 a | b | a XOR b
---+---+--------
 0 | 0 |    0
 0 | 1 |    1
 1 | 0 |    1
 1 | 1 |    0

แฮคเกอร์ไม่ได้ให้อะไรกับอินพุตเลย


0

รหัสที่มาสำหรับรุ่นต่างๆของhashCode()ในjava.util.Arraysคือการอ้างอิงที่ดีสำหรับของแข็งขั้นตอนวิธีการใช้งานทั่วไปคร่ำเครียด พวกเขาเข้าใจและแปลเป็นภาษาโปรแกรมอื่น ๆ ได้ง่าย

การใช้งานแบบหลายแอตทริบิวต์ส่วนใหญ่เป็นhashCode()ไปตามรูปแบบนี้:

public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

คุณสามารถค้นหา StackOverflow Q & As อื่น ๆ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเวทย์มนตร์ที่อยู่เบื้องหลัง31และทำไมรหัส Java จึงใช้บ่อย มันไม่สมบูรณ์ แต่มีคุณสมบัติทั่วไปที่ดีมาก


2
ค่าเริ่มต้นของ Java "คูณด้วย 31 และเพิ่ม / สะสม" แฮชจะถูกโหลดด้วยการชน (เช่นการstringชนใด ๆกับstring + "AA"IIRC) และเมื่อนานมาแล้วพวกเขาต้องการไม่ได้อบในอัลกอริทึมนั้นลงในข้อมูลจำเพาะ ที่กล่าวว่าการใช้จำนวนคี่ที่มากขึ้นพร้อมการตั้งค่าบิตเพิ่มเติมและการเพิ่มกะหรือการหมุนช่วยแก้ไขปัญหานั้นได้ 'มิกซ์' ของ MurmurHash3 ทำสิ่งนี้
Scott Carey

0

แฮคเกอร์ไม่ละเว้นบางส่วนของปัจจัยการผลิตบางครั้งเหมือนหรือและและ

หากคุณใช้AND (X, Y)เช่นและป้อนฟีดXด้วย false ดังนั้นอินพุตYไม่สำคัญ ... และอาจต้องการอินพุตสำหรับเรื่องเมื่อรวมแฮช

หากคุณใช้XOR (X, Y)ดังนั้นทั้งสองอินพุตนั้นสำคัญเสมอ จะไม่มีค่า X ที่ Y ไม่สำคัญ หากมีการเปลี่ยนแปลง X หรือ Y เอาต์พุตจะสะท้อนให้เห็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.