UUID มีความโดดเด่นอย่างไร


451

ปลอดภัยแค่ไหนที่จะใช้ UUID เพื่อระบุสิ่งที่ไม่ซ้ำกัน (ฉันใช้มันสำหรับไฟล์ที่อัปโหลดไปยังเซิร์ฟเวอร์) ตามที่ฉันเข้าใจมันเป็นไปตามตัวเลขสุ่ม อย่างไรก็ตามสำหรับฉันแล้วมันมีเวลามากพอที่จะทำซ้ำตัวเองในที่สุดโดยโอกาสที่บริสุทธิ์ มีระบบที่ดีขึ้นหรือมีรูปแบบบางประเภทที่ช่วยบรรเทาปัญหานี้หรือไม่?


11
สำหรับค่าพอขนาดใหญ่ของ "เวลาพอ" :)

91
"UUID มีความพิเศษเพียงใด" ฉันเชื่อว่าเป็นเอกลักษณ์ในระดับสากล ;)
ไมล์

29
และถ้าคุณไม่วางแผนที่จะพัฒนาบนดาวศุกร์ GUID ควรจะพอเพียง
skaffman

1
รายละเอียดเพิ่มเติมและกำเนิดที่นี่: กำเนิด uuid ออนไลน์
เดฟ

2
"ไม่ซ้ำกัน" หมายถึงไม่เคยชน ถ้ามันมีศักยภาพใด ๆ ที่จะชนกันก็ไม่ซ้ำกัน ดังนั้นตามคำนิยาม UUID จึงไม่ซ้ำกันและปลอดภัยเฉพาะเมื่อคุณเตรียมพร้อมสำหรับการชนที่อาจเกิดขึ้นโดยไม่คำนึงถึงโอกาสในการชน มิฉะนั้นโปรแกรมของคุณไม่ถูกต้อง คุณสามารถพูดว่า UUID ว่า "เกือบจะไม่เหมือนใคร" แต่ไม่ได้หมายความว่ามันจะ "ไม่เหมือนใคร"
Eonil

คำตอบ:


446

ปลอดภัยมาก:

ความเสี่ยงต่อปีของบุคคลที่ได้รับอุกกาบาตถูกประเมินว่าเป็นโอกาสครั้งเดียวใน 17 พันล้านซึ่งหมายความว่ามีความน่าจะเป็นประมาณ 0.00000000006 (6 × 10 -11 ) เทียบเท่ากับอัตราต่อรองของการสร้าง UUID ในหนึ่งปีและมีหนึ่งสำเนา กล่าวอีกนัยหนึ่งหลังจากสร้าง 1 พันล้าน UUID ทุก ๆ วินาทีในอีก 100 ปีข้างหน้าความน่าจะเป็นที่จะสร้างซ้ำเพียงครั้งเดียวจะอยู่ที่ประมาณ 50%

ข้อแม้:

อย่างไรก็ตามความน่าจะเป็นเหล่านี้จะเกิดขึ้นก็ต่อเมื่อมีการสร้าง UUID โดยใช้เอนโทรปีที่เพียงพอ มิฉะนั้นความน่าจะเป็นที่ซ้ำซ้อนอาจสูงขึ้นอย่างมีนัยสำคัญเนื่องจากการกระจายทางสถิติอาจต่ำกว่า ในกรณีที่จำเป็นต้องใช้ตัวระบุที่ไม่ซ้ำกันสำหรับแอปพลิเคชั่นแบบกระจายดังนั้น UUID จึงไม่ขัดแย้งกันแม้เมื่อรวมข้อมูลจากอุปกรณ์ต่าง ๆ การสุ่มของเมล็ดและเครื่องกำเนิดไฟฟ้าที่ใช้บนอุปกรณ์ทุกชิ้นจะต้องเชื่อถือได้ตลอดอายุการใช้งาน ในกรณีที่ไม่สามารถทำได้ RFC4122 แนะนำให้ใช้ตัวแปรเนมสเปซแทน

แหล่งที่มา: ความน่าจะเป็น UUID แบบสุ่มของส่วนที่ซ้ำกันของบทความ Wikipedia เกี่ยวกับตัวระบุที่ไม่ซ้ำแบบสากล (ลิงก์นำไปสู่การแก้ไขตั้งแต่เดือนธันวาคม 2559 ก่อนที่จะทำการแก้ไขส่วนนั้น)

ยังเห็นส่วนปัจจุบันในเรื่องเดียวกันในบทความระบุเฉพาะสากลเดียวกันชน


22
ฉันชอบส่วนนี้จาก Wikipedia: อย่างไรก็ตามความน่าจะเป็นเหล่านี้จะเกิดขึ้นก็ต่อเมื่อ UUID นั้นถูกสร้างขึ้นโดยใช้เอนโทรปีที่เพียงพอ มิฉะนั้นความน่าจะเป็นที่ซ้ำซ้อนอาจสูงขึ้นอย่างมีนัยสำคัญเนื่องจากการกระจายทางสถิติอาจต่ำกว่า ดังนั้นโอกาสที่แท้จริงในการทำซ้ำการสังเกตประโยคนี้คืออะไร เราไม่สามารถสร้างตัวเลขสุ่มที่แท้จริงบนคอมพิวเตอร์ได้ไหม
ชาย

6
อันที่จริงงานจำนวนมากได้เข้าไปค้นหาวิธีที่จะแนะนำเอนโทรปี ("การสุ่มของจริง" ผมว่าคุณคงเรียกมันว่า) เท่าที่จะเป็นไปได้ใน API จำนวนสุ่ม ดูen.wikipedia.org/wiki/Entropy_%28computing%29
broofa

4
นั่นเป็นความน่าจะเป็นที่จะเกิดการชนที่สูงกว่าที่ฉันคาดไว้ ฉันเดาว่า
คาเมรอน

คุณยืนยันได้หรือไม่ว่าการใช้ UUID จะปลอดภัยระหว่างการเรียกใช้แอปพลิเคชัน (เช่นสคริปต์ python)
George Sp

ตัวอย่างที่ดี ... : D
NuttLoose

151

ถ้าโดย "ให้เวลามากพอ" คุณหมายถึง 100 ปีและคุณสร้างมันด้วยอัตราพันล้านต่อวินาทีใช่คุณมีโอกาส 50% ที่จะมีการปะทะกันหลังจาก 100 ปี


185
แต่หลังจากใช้พื้นที่จัดเก็บ 256 Exabytes สำหรับรหัสเหล่านั้นเท่านั้น
Bob Aman

16
สิ่งที่ตลกคือคุณสามารถสร้าง 2 ในแถวที่เหมือนกันแน่นอนในระดับที่เหลือเชื่อความบังเอิญโชคและการแทรกแซงจากสวรรค์ แต่ถึงแม้จะมีราคาที่ไม่อาจหยั่งรู้ได้ก็ยังเป็นไปได้! : D ใช่มันจะไม่เกิดขึ้น เพียงแค่พูดเพื่อความสนุกในการคิดเกี่ยวกับช่วงเวลานั้นเมื่อคุณสร้างสำเนา! วิดีโอหน้าจอ!
scalabl3

4
ความเป็นเอกลักษณ์ล้วนเป็นเพราะการสุ่มหรือไม่? หรือมีปัจจัยอื่น ๆ ? (เช่นการประทับเวลา, IP และอื่น ๆ )
Weishi Zeng

15
@TheTahaan นั่นไม่ใช่ความหมายแบบสุ่ม ไม่ได้หมายความว่า "คาดเดาไม่ได้" - โดยปกติแล้วพวกเขาจะทำตามการกระจายบางอย่าง หากคุณพลิก 10 เหรียญโอกาสที่จะได้รับ 2 หัวตามด้วย 3 ก้อยตามด้วย 5 หัวจะค่อนข้างต่ำ (2 ^ -10 ประมาณ 0.001) มันสุ่มอย่างแท้จริง แต่เราสามารถรู้โอกาสที่จะได้ผลลัพธ์ที่แน่นอน เราไม่สามารถพูดได้ล่วงหน้าว่าจะเกิดขึ้นหรือไม่
Richard Rast

5
เพียงเพื่ออธิบายว่าการใช้งานผิดหรือไม่พวกเขากำลังใช้ UUID รุ่นที่ 1 ซึ่งอาศัยการรวมกันของการประทับเวลาและที่อยู่ Mac เพื่อความเป็นเอกลักษณ์ อย่างไรก็ตามหากคุณสร้าง UUID เร็วพอการประทับเวลาจะยังไม่เพิ่มขึ้น ในสถานการณ์นี้อัลกอริทึมการสร้าง UUID ของคุณควรติดตามการประทับเวลาครั้งล่าสุดที่ใช้และเพิ่มขึ้นทีละ 1 พวกเขาล้มเหลวอย่างชัดเจนในการทำตามขั้นตอนนั้น อย่างไรก็ตาม UUID ทุกรุ่นที่ 1 สร้างขึ้นอย่างถูกต้องโดยเครื่องเดียวกันในช่วงเวลาสั้น ๆ จะมีความคล้ายคลึงกันอย่างชัดเจน แต่ควรจะมีลักษณะเฉพาะ
Bob Aman

103

มี UUID มากกว่าหนึ่งประเภทดังนั้น "วิธีที่ปลอดภัย" ขึ้นอยู่กับประเภท (ซึ่งข้อมูลจำเพาะ UUID เรียกว่า "รุ่น") ที่คุณใช้งานอยู่

  • เวอร์ชัน 1 คือเวลาตามที่รวมกับที่อยู่ MAC UUID 128 บิตมี 48 บิตสำหรับที่อยู่ MAC ของการ์ดเครือข่าย (ซึ่งได้รับมอบหมายจากผู้ผลิตอย่างไม่ซ้ำกัน) และนาฬิกา 60 บิตที่มีความละเอียด 100 นาโนวินาที นาฬิกานั่นล้อมรอบใน 3603 ADดังนั้น UUID เหล่านี้จะปลอดภัยอย่างน้อยก็จนกว่า (เว้นแต่คุณต้องการ UUID ใหม่มากกว่า 10 ล้านต่อวินาทีหรือมีคนโคลนการ์ดเครือข่ายของคุณ) ฉันพูดว่า "อย่างน้อย" เพราะนาฬิกาเริ่มต้นเมื่อวันที่ 15 ตุลาคม ค.ศ. 1582 ดังนั้นคุณมีเวลาประมาณ 400 ปีหลังจากที่นาฬิกาปิดล้อมก่อนที่จะมีความซ้ำซ้อนเล็กน้อย

  • เวอร์ชัน 4 คือหมายเลขสุ่ม UUID มีหกบิตคงที่และส่วนที่เหลือของ UUID คือ 122 บิตของการสุ่ม ดูวิกิพีเดียหรือการวิเคราะห์อื่น ๆ ที่อธิบายว่ามีความซ้ำซ้อนมากน้อยเพียงใด

  • เวอร์ชัน 3 ใช้ MD5 และเวอร์ชัน 5 ใช้ SHA-1 เพื่อสร้าง 122 บิตเหล่านั้นแทนตัวสร้างตัวเลขสุ่มหรือหลอกเทียม ดังนั้นในแง่ของความปลอดภัยมันก็เหมือนกับเวอร์ชั่น 4 ที่เป็นประเด็นทางสถิติ (ตราบใดที่คุณตรวจสอบให้แน่ใจว่าอัลกอริธึมการย่อยนั้นกำลังประมวลผลที่ไม่ซ้ำกันอยู่เสมอ)

  • เวอร์ชัน 2 นั้นคล้ายคลึงกับเวอร์ชัน 1 แต่ด้วยนาฬิกาขนาดเล็กกว่า แต่เนื่องจาก UUID เวอร์ชัน 2 นั้นใช้สำหรับ DCE คุณไม่ควรใช้สิ่งเหล่านี้

ดังนั้นสำหรับปัญหาในทางปฏิบัติทั้งหมดพวกเขาจะปลอดภัย หากคุณรู้สึกไม่สบายใจที่จะทิ้งความเป็นไปได้ที่จะเกิดขึ้น (เช่นคุณเป็นคนที่กังวลเกี่ยวกับโลกที่ถูกทำลายโดยดาวเคราะห์น้อยขนาดใหญ่ในชีวิตของคุณ) เพียงแค่ให้แน่ใจว่าคุณใช้เวอร์ชั่น 1 UUID และรับประกันว่าจะไม่ซ้ำกัน ในชีวิตของคุณเว้นแต่ว่าคุณวางแผนที่จะมีชีวิตอยู่ในช่วง 3603 AD)

เหตุใดทุกคนจึงไม่ใช้เพียง UUID เวอร์ชัน 1 นั่นเป็นเพราะ UUID เวอร์ชัน 1 เปิดเผยที่อยู่ MAC ของเครื่องที่สร้างขึ้นและพวกเขาสามารถคาดเดาได้ - สองสิ่งที่อาจมีผลกระทบด้านความปลอดภัยสำหรับแอปพลิเคชันที่ใช้ UUID เหล่านั้น


1
การกำหนดค่าเริ่มต้นเป็นเวอร์ชัน 1 UUID มีปัญหาร้ายแรงเมื่อสร้างโดยเซิร์ฟเวอร์เดียวกันสำหรับหลาย ๆ คน UUID เวอร์ชัน 4 เป็นค่าเริ่มต้นของฉันเนื่องจากคุณสามารถเขียนสิ่งที่จะสร้างในภาษาหรือแพลตฟอร์มใด ๆ ได้อย่างรวดเร็ว (รวมถึงจาวาสคริปต์)
Justin Bozonier

1
@Hoylen อธิบายได้ดี! แต่เรื่องนี้ต้องพูดเกินจริงมากไหม?
Dinoop paloli

1
ในทางทฤษฎีมันถูกกำหนดโดยผู้ผลิตที่ไม่ซ้ำกัน
OrangeDog

4
เราไม่จำเป็นต้องสร้าง UUIDs จำนวน 10 ล้านเวอร์ชั่นในหนึ่งวินาที เราจะต้องสร้าง UUID เพียง 16,384 ชุดภายในช่วงของ "tick" เดียวเพื่อที่จะล้นหมายเลขลำดับ ฉันได้เห็นสิ่งนี้เกิดขึ้นกับการใช้งานที่อาศัยความไร้เดียงสาบนแหล่งสัญญาณนาฬิกาที่ (1) มีความละเอียดระดับμsและ (2) ไม่รับประกันว่าจะเป็นแบบโมโนโทนิก ระวังรหัสของ UUID ที่คุณใช้และระมัดระวังเป็นพิเศษกับเครื่องกำเนิดไฟฟ้า UUID ตามเวลา พวกมันยากที่จะทำถูกต้องดังนั้นให้ทดสอบการโหลดก่อนใช้
Mike Strobel

ช่วงเวลาระหว่าง v4 UUID ที่สร้างขึ้นอาจนำไปสู่ความน่าจะเป็นของการชนมากขึ้นหรือไม่? ฉันหมายถึงในแอปพลิเคชั่นการจราจรหนาแน่นสมมติว่ามีการสร้าง uuids หลายพันรายการในเวลาเดียวกันมีโอกาสที่จะเกิดการชนมากกว่าถ้ามีการสร้าง uuids ในปริมาณที่เท่ากันในช่วงเวลาที่นานขึ้น?
Jonathan

18

คำตอบนี้อาจขึ้นอยู่กับรุ่น UUID เป็นส่วนใหญ่

เครื่องกำเนิดไฟฟ้า UUID จำนวนมากใช้หมายเลขสุ่มรุ่น 4 อย่างไรก็ตามสิ่งเหล่านี้ใช้ Pseudo เป็น Random Number Generator เพื่อสร้าง

ถ้า PRNG ที่มีคุณภาพต่ำซึ่งมีช่วงเวลาน้อยถูกใช้เพื่อสร้าง UUID ฉันจะบอกว่ามันไม่ปลอดภัยเลย

ดังนั้นมันจึงปลอดภัยพอ ๆ กับอัลกอริธึมที่ใช้ในการสร้างมัน

ในทางกลับกันถ้าคุณรู้คำตอบสำหรับคำถามเหล่านี้แล้วฉันคิดว่ารุ่น 4 uuid ควรจะปลอดภัยมากที่จะใช้ ในความเป็นจริงฉันใช้มันเพื่อระบุบล็อกในระบบไฟล์เครือข่ายบล็อกและจนถึงขณะนี้ยังไม่มีการปะทะกัน

ในกรณีของฉัน PRNG ที่ฉันใช้คือ twers mersenne และฉันระมัดระวังในการเพาะเมล็ดซึ่งมาจากหลายแหล่งรวมถึง / dev / urandom Mersenne twister มีระยะเวลา 2 ^ 19937 - 1 มันจะเป็นเวลานานมากก่อนที่ฉันจะเห็น uuid ซ้ำ


14

ข้อความจากWikipedia :

ดังนั้นทุกคนสามารถสร้าง UUID และใช้มันเพื่อระบุบางสิ่งด้วยความมั่นใจอย่างสมเหตุสมผลว่าตัวระบุจะไม่ถูกใช้โดยไม่ได้ตั้งใจโดยใครก็ตามเพื่อสิ่งอื่นใด

อธิบายรายละเอียดที่ดีเกี่ยวกับความปลอดภัยของมัน ดังนั้นเพื่อตอบคำถามของคุณ: ใช่มันปลอดภัยเพียงพอ


9

ฉันเห็นด้วยกับคำตอบอื่น ๆ UUID นั้นปลอดภัยเพียงพอสำหรับการใช้งานจริงเกือบทั้งหมด1และแน่นอนสำหรับคุณ

แต่สมมติว่าพวกเขาไม่ใช่

มีระบบที่ดีขึ้นหรือมีรูปแบบบางประเภทที่ช่วยบรรเทาปัญหานี้หรือไม่?

นี่คือแนวทางสองสามข้อ:

  1. ใช้ UUID ที่ใหญ่กว่า ตัวอย่างเช่นแทนที่จะเป็นบิตสุ่ม 128 บิตให้ใช้ 256 หรือ 512 หรือ ... แต่ละบิตที่คุณเพิ่มลงใน UUID ของสไตล์ -4 จะลดความน่าจะเป็นของการชนโดยครึ่งหนึ่งโดยสมมติว่าคุณมีแหล่งเอนโทรปี2 ที่เชื่อถือได้.

  2. สร้างบริการส่วนกลางหรือกระจายที่สร้าง UUID และบันทึกแต่ละรายการที่เคยออกมา ทุกครั้งที่มันสร้างใหม่มันจะตรวจสอบว่า UUID ไม่เคยออกมาก่อน บริการดังกล่าวจะเป็นเทคนิคในการดำเนินการตรงไปตรงมา (ฉันคิดว่า) ถ้าเราสันนิษฐานว่าคนที่ใช้บริการมีความน่าเชื่อถืออย่างแน่นอนไม่เน่าเปื่อยและอื่น ๆ น่าเสียดายที่พวกเขาไม่ได้ ... โดยเฉพาะอย่างยิ่งเมื่อมีความเป็นไปได้ที่องค์กรความมั่นคงของรัฐบาลจะเข้าไปแทรกแซง ดังนั้นวิธีนี้อาจเป็นไปไม่ได้และอาจเป็นไปไม่ได้3ในโลกแห่งความจริง


1 - หากเอกลักษณ์ของ UUID กำหนดว่าขีปนาวุธนิวเคลียร์ได้เปิดตัวในเมืองหลวงของประเทศของคุณหรือไม่เพื่อนร่วมชาติของคุณจำนวนมากจะไม่เชื่อโดย "ความน่าจะเป็นนั้นต่ำมาก" ดังนั้นคุณสมบัติ "เกือบทั้งหมด" ของฉัน

2 - และนี่คือคำถามเชิงปรัชญาสำหรับคุณ มีอะไรที่เคยสุ่มอย่างแท้จริง? เราจะรู้ได้อย่างไรว่ามันไม่? จักรวาลเป็นที่เรารู้ว่ามันเป็นแบบจำลองหรือไม่? มีพระเจ้าที่อาจ "ปรับแต่ง" กฎของฟิสิกส์เพื่อเปลี่ยนแปลงผลลัพธ์หรือไม่?

3 - ถ้าใครรู้บทความวิจัยเกี่ยวกับปัญหานี้โปรดแสดงความคิดเห็น


ฉันแค่อยากจะชี้ให้เห็นว่าวิธีการที่ 2 นั้นเอาชนะจุดประสงค์หลักของการใช้ UUID เป็นหลักและคุณก็อาจใช้เลขลำดับคลาสสิคที่จุดนั้น
Petr Vnenk

ฉันไม่เห็นด้วย. ข้อบกพร่องใน ID ที่มีหมายเลขต่อเนื่องคือพวกเขาเดาง่ายเกินไป คุณควรจะสามารถใช้วิธีที่ 2 ในลักษณะที่ทำให้ UUIDs เดาได้ยาก
Stephen C

8

แบบแผน UUID โดยทั่วไปจะใช้ไม่เพียง แต่องค์ประกอบแบบหลอกเทียมเท่านั้น แต่ยังใช้เวลาของระบบในปัจจุบันและรหัสฮาร์ดแวร์ที่ไม่ซ้ำใครบางประเภทหากมีเช่นเครือข่าย MAC address

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


6

เคยทำมาหลายปีแล้ว ไม่พบปัญหา

ฉันมักจะตั้งค่าฐานข้อมูลของฉันให้มีหนึ่งตารางที่มีปุ่มทั้งหมดและวันที่แก้ไขและเช่นนั้น ยังไม่พบปัญหากับคีย์ซ้ำกันเลยทีเดียว

ข้อเสียเปรียบเพียงอย่างเดียวที่มีก็คือตอนที่คุณเขียนแบบสอบถามเพื่อค้นหาข้อมูลบางอย่างรวดเร็วคุณกำลังคัดลอกและวางกุญแจจำนวนมาก คุณไม่มีรหัสย่อที่จดจำได้ง่ายอีกต่อไป


5

นี่คือตัวอย่างการทดสอบสำหรับคุณในการทดสอบว่ามันไม่ซ้ำกัน แรงบันดาลใจจากความคิดเห็นของ @ scalabl3

สิ่งที่ตลกคือคุณสามารถสร้าง 2 ในแถวที่เหมือนกันแน่นอนในระดับที่ไม่น่าเชื่อว่าจะเกิดขึ้นโชคและการแทรกแซงจากสวรรค์ : D ใช่มันจะไม่เกิดขึ้น เพียงแค่พูดเพื่อความสนุกในการคิดเกี่ยวกับช่วงเวลานั้นเมื่อคุณสร้างสำเนา! วิดีโอหน้าจอ! - scalabl3 20 ต.ค. 58 ที่ 19:11

หากคุณรู้สึกว่าโชคดีให้ทำเครื่องหมายในช่องทำเครื่องหมายมันจะตรวจสอบ ID ที่สร้างขึ้นในปัจจุบันเท่านั้น หากคุณต้องการตรวจสอบประวัติปล่อยให้มันไม่ถูกตรวจสอบ โปรดทราบว่าคุณอาจหมด RAM ในบางช่วงหากคุณไม่ได้เลือก ฉันพยายามทำให้มันเป็นมิตรกับ cpu ดังนั้นคุณสามารถยกเลิกได้อย่างรวดเร็วเมื่อจำเป็นเพียงกดปุ่มเรียกใช้อีกครั้งหรือออกจากหน้า

Math.log2 = Math.log2 || function(n){ return Math.log(n) / Math.log(2); }
  Math.trueRandom = (function() {
  var crypt = window.crypto || window.msCrypto;

  if (crypt && crypt.getRandomValues) {
      // if we have a crypto library, use it
      var random = function(min, max) {
          var rval = 0;
          var range = max - min;
          if (range < 2) {
              return min;
          }

          var bits_needed = Math.ceil(Math.log2(range));
          if (bits_needed > 53) {
            throw new Exception("We cannot generate numbers larger than 53 bits.");
          }
          var bytes_needed = Math.ceil(bits_needed / 8);
          var mask = Math.pow(2, bits_needed) - 1;
          // 7776 -> (2^13 = 8192) -1 == 8191 or 0x00001111 11111111

          // Create byte array and fill with N random numbers
          var byteArray = new Uint8Array(bytes_needed);
          crypt.getRandomValues(byteArray);

          var p = (bytes_needed - 1) * 8;
          for(var i = 0; i < bytes_needed; i++ ) {
              rval += byteArray[i] * Math.pow(2, p);
              p -= 8;
          }

          // Use & to apply the mask and reduce the number of recursive lookups
          rval = rval & mask;

          if (rval >= range) {
              // Integer out of acceptable range
              return random(min, max);
          }
          // Return an integer that falls within the range
          return min + rval;
      }
      return function() {
          var r = random(0, 1000000000) / 1000000000;
          return r;
      };
  } else {
      // From http://baagoe.com/en/RandomMusings/javascript/
      // Johannes Baagøe <baagoe@baagoe.com>, 2010
      function Mash() {
          var n = 0xefc8249d;

          var mash = function(data) {
              data = data.toString();
              for (var i = 0; i < data.length; i++) {
                  n += data.charCodeAt(i);
                  var h = 0.02519603282416938 * n;
                  n = h >>> 0;
                  h -= n;
                  h *= n;
                  n = h >>> 0;
                  h -= n;
                  n += h * 0x100000000; // 2^32
              }
              return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
          };

          mash.version = 'Mash 0.9';
          return mash;
      }

      // From http://baagoe.com/en/RandomMusings/javascript/
      function Alea() {
          return (function(args) {
              // Johannes Baagøe <baagoe@baagoe.com>, 2010
              var s0 = 0;
              var s1 = 0;
              var s2 = 0;
              var c = 1;

              if (args.length == 0) {
                  args = [+new Date()];
              }
              var mash = Mash();
              s0 = mash(' ');
              s1 = mash(' ');
              s2 = mash(' ');

              for (var i = 0; i < args.length; i++) {
                  s0 -= mash(args[i]);
                  if (s0 < 0) {
                      s0 += 1;
                  }
                  s1 -= mash(args[i]);
                  if (s1 < 0) {
                      s1 += 1;
                  }
                  s2 -= mash(args[i]);
                  if (s2 < 0) {
                      s2 += 1;
                  }
              }
              mash = null;

              var random = function() {
                  var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
                  s0 = s1;
                  s1 = s2;
                  return s2 = t - (c = t | 0);
              };
              random.uint32 = function() {
                  return random() * 0x100000000; // 2^32
              };
              random.fract53 = function() {
                  return random() +
                      (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
              };
              random.version = 'Alea 0.9';
              random.args = args;
              return random;

          }(Array.prototype.slice.call(arguments)));
      };
      return Alea();
  }
}());

Math.guid = function() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c)    {
      var r = Math.trueRandom() * 16 | 0,
          v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
  });
};
function logit(item1, item2) {
    console.log("Do "+item1+" and "+item2+" equal? "+(item1 == item2 ? "OMG! take a screenshot and you'll be epic on the world of cryptography, buy a lottery ticket now!":"No they do not. shame. no fame")+ ", runs: "+window.numberofRuns);
}
numberofRuns = 0;
function test() {
   window.numberofRuns++;
   var x = Math.guid();
   var y = Math.guid();
   var test = x == y || historyTest(x,y);

   logit(x,y);
   return test;

}
historyArr = [];
historyCount = 0;
function historyTest(item1, item2) {
    if(window.luckyDog) {
       return false;
    }
    for(var i = historyCount; i > -1; i--) {
        logit(item1,window.historyArr[i]);
        if(item1 == history[i]) {
            
            return true;
        }
        logit(item2,window.historyArr[i]);
        if(item2 == history[i]) {
            
            return true;
        }

    }
    window.historyArr.push(item1);
    window.historyArr.push(item2);
    window.historyCount+=2;
    return false;
}
luckyDog = false;
document.body.onload = function() {
document.getElementById('runit').onclick  = function() {
window.luckyDog = document.getElementById('lucky').checked;
var val = document.getElementById('input').value
if(val.trim() == '0') {
    var intervaltimer = window.setInterval(function() {
         var test = window.test();
         if(test) {
            window.clearInterval(intervaltimer);
         }
    },0);
}
else {
   var num = parseInt(val);
   if(num > 0) {
        var intervaltimer = window.setInterval(function() {
         var test = window.test();
         num--;
         if(num < 0 || test) {
    
         window.clearInterval(intervaltimer);
         }
    },0);
   }
}
};
};
Please input how often the calulation should run. set to 0 for forever. Check the checkbox if you feel lucky.<BR/>
<input type="text" value="0" id="input"><input type="checkbox" id="lucky"><button id="runit">Run</button><BR/>


ลองด้วย UUID RFC 4122 เวอร์ชัน 1 (วันที่และที่อยู่ MAC)
zaph

มันเคยเป็นที่เห็นได้ชัดอย่างรวดเร็วจนกระทั่งมีการอัปเดตของ Chrome ฉันสังเกตเห็นเหมือนกัน 4 สัปดาห์ที่ผ่านมา
Tschallacka

3

ผมไม่ทราบว่าถ้าเรื่องนี้ให้คุณ แต่เก็บไว้ในใจว่าguid ของที่ไม่ซ้ำกันทั่วโลก แต่สตริง guid ของไม่ได้


1
โปรดทราบว่าการอ้างอิงที่เชื่อมโยงที่นี่พูดถึง UUID รุ่นที่ 1 (ซึ่งนำข้อมูลเกี่ยวกับการสร้างคอมพิวเตอร์ ฯลฯ ไปยัง id) คำตอบอื่น ๆ ส่วนใหญ่พูดถึงเวอร์ชั่น 4 (ซึ่งสุ่มทั้งหมด) บทความ Wikipedia ที่ถูกเชื่อมโยงข้างต้นen.wikipedia.org/wiki/Universally_unique_identifierอธิบาย UUIDs ประเภทต่างๆ
kratenko

3

สำหรับ UUID4 ฉันคิดว่ามันมี ID ประมาณมากเท่าที่มีเม็ดทรายในกล่องรูปลูกบาศก์ที่มีด้านยาว 360,000 กม. นั่นคือกล่องที่มีด้านยาวกว่าเส้นผ่านศูนย์กลางของดาวพฤหัสประมาณ 2 1/2 เท่า

ทำงานเพื่อให้มีคนบอกฉันได้ว่าฉันทำเลอะเทอะหรือไม่:

  • ปริมาตรของเม็ดทราย 0.00947mm ^ 3 ( ผู้พิทักษ์ )
  • UUID4 มี 122 บิตสุ่ม -> 5.3e36 ค่าที่เป็นไปได้ ( วิกิพีเดีย )
  • ปริมาตรของทรายหลายเม็ด = 5.0191e34 mm ^ 3 หรือ 5.0191e + 25m ^ 3
  • ความยาวด้านของกล่องลูกบาศก์ที่มีปริมาตรนั้น = 3.69E8m หรือ 369,000 กม
  • เส้นผ่านศูนย์กลางของดาวพฤหัสบดี: 139,820km (google)

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