1 คะแนน โดย GN⁺ 2 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • วันนี้ฐานข้อมูลตรวจพบ UUID v4 ซ้ำกัน และค่าที่มีอยู่เดิมตรงกับ b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd ของเรคคอร์ดที่ถูกเพิ่มในปี 2025 แบบตรงกันทุกประการ
  • แพ็กเกจที่ใช้อยู่คือ uuid ของ npm โดยระบุว่าใช้วิธี import { v4 as uuidv4 } from "uuid"; แล้วสร้างด้วย const document_id = uuidv4(); ก่อนนำไปใส่ในฐานข้อมูล
  • ในฐานข้อมูลมีเพียงประมาณ 15,000 เรคคอร์ด เท่านั้น จึงดูแทบเป็นไปไม่ได้ในเชิงสถิติ และกำลังถามว่ามีใครเคยเจอเรื่องแบบเดียวกันไหม

1 ความคิดเห็น

 
GN⁺ 2 시간 전
ความคิดเห็นจาก Hacker News
  • jandrewrogers: เรื่องนี้เกิดบ่อยกว่าที่คิดมาก ความปลอดภัยของ UUIDv4 ตั้งอยู่บนสมมติฐานว่ามีแหล่งเอนโทรปีคุณภาพสูง แต่สมมติฐานนี้พังได้ง่ายจากฮาร์ดแวร์เสีย บั๊กซอฟต์แวร์ทั่วไป หรือความเข้าใจเรื่องเอนโทรปีของนักพัฒนาที่ไม่เพียงพอ
    การตรวจจับว่าแหล่งเอนโทรปีพังหรือเปล่ามีต้นทุนค่อนข้างสูง เลยแทบไม่มีใครทำ และก็มักจะรู้ตัวกันหลังจากเกิดการชนกันแล้วเท่านั้น ดังนั้นในระบบที่ต้องการความเชื่อถือสูงและการรับประกันสูงจำนวนมากจึงห้ามใช้ UUIDv4 อย่างชัดเจน

    • LocalH: นี่แหละเหตุผลที่ CloudFlare ทำ กำแพงโคมลาวา ขึ้นมา ไม่ใช่ว่ามันเป็นแหล่งเอนโทรปีมหาศาลในตัวเองเท่านั้น แต่ยังช่วยให้คนที่ไม่ค่อยเข้าใจการสร้างเลขสุ่มกับแนวคิดเรื่องเอนโทรปีมองเห็นภาพได้ด้วย
      ยิ่งมีแหล่งเอนโทรปีมากก็ยิ่งดี และหลายแหล่งควรเป็นแบบไม่กำหนดแน่นอน แม้แต่ในเกมเล็ก ๆ ถ้าเอาค่าพิกัดเมาส์ ช่วงเวลาระหว่างการกดปุ่ม หรือจำนวนเฟรมก่อนกดปุ่มเริ่ม ไปผสมใน initial seed ก็จะทำให้เดายากขึ้นมาก แม้ภายในยังใช้ตัวสร้างเลขสุ่มเทียมอยู่ก็ตาม ถ้า CloudFlare ใช้แหล่งเอนโทรปีน้อยกว่า 100 แหล่งก็คงน่าผิดหวัง
    • Groxx: เคยเห็นการซ้ำที่ดูสมเหตุสมผลจากฮาร์ดแวร์มีปัญหา และในไลบรารี UUID บางตัวก็พบบ่อยมากกับ รูปแบบการซ้ำที่ด้านท้ายถูกเติม 0 จำนวนมาก
      สิ่งนี้เกิดขึ้นได้ถ้าไม่ตรวจค่าที่คืนกลับมาแบบที่เคยเกิดใน Go สมัยก่อน เช่น “ขอ N ไบต์ แต่ได้กลับมาแค่ 3 ไบต์ ดังนั้นต้องขออีก N-3 ไบต์” เพราะฮาร์ดแวร์หรือระบบปฏิบัติการส่วนใหญ่ไม่ค่อยทำให้ปัญหานี้โผล่ ผู้คนจึงไม่ตรวจสอบ จนวันหนึ่งมันไปโผล่ใน production เป็นการชนกันหลายหมื่นครั้ง
    • thecloud: อยากรู้ว่าระบบที่ต้องการความเชื่อถือสูงใช้ทางเลือกอะไรแทน UUIDv4
  • throwaway_19sz: ฟังดูตลกจนไม่น่าเชื่อแต่เป็นเรื่องจริง เมื่อ 10 ปีก่อนเพื่อนผมเข้าร่วมเป็น CTO ของสตาร์ตอัปโตเร็วแห่งหนึ่ง บริษัทมีนักพัฒนาประมาณ 200 คน และในสัปดาห์แรกก็พบว่ามี ไมโครเซอร์วิสสำหรับสร้าง UUID โดยเฉพาะ
    มีวิศวกรดูแล endpoint เดียวถึง 3 คน แถมยังมีคนดูแลฐานข้อมูลอีกด้วย ถ้าทีมไหนต้องการ UUID “ที่ปลอดภัย” ตัวใหม่ ก็ต้องเรียกบริการนี้ทุกครั้ง บริการจะสร้าง UUID ขึ้นมา ตรวจใน DB ของตัวเองว่ามี UUID นี้เคยออกไปแล้วหรือไม่ ถ้าไม่มีก็ insert แล้วส่งกลับให้ ไม่รู้ว่าทำไปเพื่อความสบายใจหรือเปล่า แต่ทีมนั้นมีทั้งกระดานคัมบังและสปรินต์ของตัวเองด้วย

    • Aurornis: ตอนเริ่มต้นผมเคยทำงานในสตาร์ตอัปที่ทรัพยากรจำกัด เลยต้องคิดรอบคอบมากทุกครั้งก่อนจะสร้างอะไรหรือรับคนเพิ่ม ตอนนั้นถ้าได้ยินเรื่องนี้คงคิดว่าเป็นนิยาย
      แต่สตาร์ตอัปที่เข้าทีหลังเป็นแบบที่ทุกครั้งที่มีคนคิดความกังวลใหม่ขึ้นมา ก็จะมีไมโครเซอร์วิสใหม่กับทีมใหม่เกิดขึ้น เป้าหมายรายไตรมาสระบุชัดเลยว่าต้องขยายขนาดทีมวิศวกรรม และทีมเล็ก ๆ 3-4 คนก็สร้างงานให้ตัวเองจากสปรินต์กับการประชุมวางแผนของตัวเอง ผมเคยเสนอให้ย้ายคนจากโปรเจกต์เสถียรไปช่วยงานด่วน แต่โดนคัดค้านเพราะขัดกับ KPI ที่ต้องเพิ่มจำนวนวิศวกรให้ถึงตัวเลขที่กำหนด
    • wongarsu: สักวันต้องมีคน optimize เรื่องนี้เป็น ตัวนับเพิ่มค่า 128 บิตระดับทั้งองค์กรทั่วโลก แน่ ๆ เอาแค่ดึงค่าปัจจุบันมา บวก 1 แล้วแจกออกไป โดยไม่ต้อง query DB ที่โตขึ้นเรื่อย ๆ ก็เป็น O(1) และเร็ว
      ถ้าต้องการ high availability และ deployment ทั่วโลก ก็ shard ได้ด้วยการให้ช่วง ID เฉพาะกับแต่ละ instance กันบิตส่วนบนบางส่วนไว้เป็น data center ID และอีกไม่กี่บิตสำหรับ instance ที่สร้าง ID ภายในนั้น เดี๋ยวก่อนนะ เหมือนเคยเห็นอะไรแบบนี้ที่ไหน… อยากรู้ว่า Twitter ยังใช้แนวนี้อยู่หรือสุดท้ายเปลี่ยนไปแล้ว
    • roryirvine: ผมเคยเห็นอะไรคล้ายกันลึกเข้าไปในบริษัทเทคใหญ่แห่งหนึ่งในซิลิคอนแวลลีย์ แต่ยิ่งซับซ้อนกว่าเพราะรายการ UUID ที่ใช้งานอยู่ทั้งหมดถูกเก็บใน บริการ CMDB ภายนอก ที่อีกแผนกดูแล
      ทุกวันจะดึง DB dump มาเช็กตอนสร้าง ID “ชั่วคราว” และจะถือว่าเป็น “ยืนยันแล้ว” ก็ต่อเมื่อส่งเข้า CMDB ถูกต้อง มี guardrail ป้องกันไม่ให้เอา ID ชั่วคราวไปใช้จริง และยังมีขั้นตอนนำ ID ที่ยืนยันแล้วแต่ไม่ได้ใช้กลับมารีไซเคิลด้วย ตอนที่ได้ยินล่าสุด พวกเขายังอยู่เดือนที่ 18 ของโปรเจกต์ 6 เดือนในการย้าย local DB cache ไป Zookeeper
  • CodesInChaos: ปกติสาเหตุมาจาก ตัวสร้างเลขสุ่มเทียมที่มี seed ไม่พอ เรื่องสำคัญคือ UUID ถูกสร้างในแบ็กเอนด์หรือฟรอนต์เอนด์
    ฝั่งฟรอนต์เอนด์เชื่อถือได้ยากโดยพื้นฐาน ไม่ว่าจะเพราะการชนกันแบบจงใจหรือเหตุผลอื่น ๆ จึงต้องมีการจัดการ collision ส่วนแบ็กเอนด์ทำให้เสถียรได้ ในอดีต VM เคยมีปัญหานี้ แต่ปัจจุบันควรจะแก้ไปแล้ว อย่างไรก็ดี ถ้า process ที่ถูก sandbox หนัก ๆ ไปใช้เส้นทางสุ่มสำรองที่ไม่ปลอดภัยก็ยังเจอได้ และการ fork process หรือ VM ก็อาจทำให้เกิด collision จากการคัดลอก state

    • danpalmer: เคยได้ยินมาว่า Segment บริษัท analytics เคยพึ่ง UUID ที่สร้างจากเว็บเบราว์เซอร์กับผลิตภัณฑ์ทั้งตัวของบริษัท พอมี browser UUID collision เกิดขึ้นทั่ว ๆ ไป เหมือนทำให้ผลิตภัณฑ์อยู่ในสภาพที่ไม่สามารถสร้างข้อมูลที่มีประโยชน์ได้จริง หวังว่าตอนนี้คงแก้ไปแล้ว
  • kst: ทำให้นึกถึงข้อความตอนหนึ่งใน “Pro Git” <https://git-scm.com/book/en/v2>
    เขายกตัวอย่างว่า ต่อให้มนุษย์ 6.5 พันล้านคนบนโลกสร้างโค้ดขนาดเท่าประวัติทั้งหมดของ Linux kernel ทุกวินาที แล้ว push เข้า Git repository เดียวขนาดมหึมา ก็ยังต้องใช้เวลาราว 2 ปี กว่าความน่าจะเป็นของ SHA-1 object collision จะถึง 50% เลยชอบสำนวนที่บอกว่า SHA-1 collision ตามธรรมชาตินั้นมีโอกาสน้อยกว่าที่สมาชิกทีมทุกคนจะตายในคืนเดียวกันจากการถูกหมาป่าจู่โจมโดยไม่เกี่ยวข้องกัน แม้ SHA-1 hash จะไม่ใช่เลขสุ่มและมี 160 บิต จึงไม่เหมือน UUIDv4 แต่ผมชอบอุปมาเรื่อง การถูกหมาป่าจู่โจมโดยไม่เกี่ยวข้องกัน

    • mega_dean: ทำให้นึกถึงหน้านี้ที่อธิบายว่าจำนวนการเรียงไพ่หนึ่งสำรับมีมากแค่ไหน: https://czep.net/weblog/52cards.html
      เป็นอุปมาประมาณว่า ต่อให้เดินรอบโลกที่เส้นศูนย์สูตรทุก 1 พันล้านปีหนึ่งก้าว และทุกครั้งที่ครบรอบหนึ่งรอบก็ตักน้ำออกจากมหาสมุทรแปซิฟิกหนึ่งหยด พอมหาสมุทรแห้งก็วางกระดาษหนึ่งแผ่น แล้วทำซ้ำจนกองกระดาษสูงถึงดวงอาทิตย์ เลขสามหลักแรกของตัวจับเวลา 52! วินาทีก็ยังไม่เปลี่ยน
    • swiftcoder: ในทางกลับกัน dictionary attack เป็นเรื่องจริงได้พอตัว และอย่างที่คนที่เผลอ commit ไฟล์ test case แบบนั้นลง Git เคยเจอมา มันสร้างปัญหาได้ไม่น้อย
    • TacticalCoder: ทีม Git ไม่ได้กำลังทำงานหนักเพื่อให้เลือกใช้ hash อื่นอย่าง SHA256 ควบคู่กับ SHA-1 ได้อยู่เหรอ?
  • e12e: มีการคุยที่เกี่ยวข้องอยู่ที่นี่: https://github.com/uuidjs/uuid/issues/546
    ตัวอย่างเช่น มีการทดสอบ crypto.getRandomValues() กับ googlebot แล้วพบว่ามันเป็นแบบ กำหนดแน่นอน

    • D2OQZG8l5BI1S06: ฟังดูสมเหตุสมผล แค่ไม่เข้าใจว่าทำไมต้องสร้าง UUID ในเบราว์เซอร์ด้วย มันเหมือนขัดกับจุดประสงค์ของมันเอง
  • adyavanapalli: เรื่องที่กำลังพูดถึงนี้หายากมาก ขนาดว่าความเป็นไปได้ที่โลกทั้งใบจะโดนดาวเคราะห์น้อยทำลายในตอนนี้ยังสูงกว่า

    • thomasmg: ไม่ได้หายากขนาดนั้น ผมเคยคำนวณไว้และพบว่ามันหายากกว่าการโดนอุกกาบาตนิดหน่อย แล้วเคยเพิ่มข้อมูลนั้นพร้อม birthday problem ลงในบทความ UUID บน Wikipedia แม้หลายปีก่อนจะถูกลบแล้วแทนที่ไป
      เคยได้ยินว่ามีผู้หญิงคนหนึ่งโดนอุกกาบาตจริงแต่รอดมาได้โดยบาดเจ็บที่ขา ถ้าเกิด UUID collision จริง ความเป็นไปได้สูงลิ่วคือมีบั๊กซอฟต์แวร์หรือคอมพิวเตอร์ผิดปกติ และอาจเป็นรังสีคอสมิกก็ได้ รังสีคอสมิกไปรบกวนหน่วยความจำหรือ CPU เกิดขึ้นบ่อยกว่าที่คนส่วนใหญ่คิด
    • delichon: ประมาณเท่าความน่าจะเป็นที่ดาวเคราะห์น้อยจะพิมพ์เครื่องหมายจุดไข่ปลาแล้วกดปุ่มเพิ่มความเห็น
    • spindump8930: อย่างที่หลายคนบอก ถ้า seed ผิด มันเกิดได้บ่อยมาก ถ้าจะเปรียบเทียบก็เหมือนโลกถูกล้อมรอบด้วยแถบดาวเคราะห์น้อยความหนาแน่นสูงแบบในนิยายวิทยาศาสตร์แล้วโดนชน
  • juancn: เป็นไปได้ไหมว่าการ initialize ตัวสร้างเลขสุ่มแปลก ๆ หรือเอนโทรปีไม่พอ? ถ้าไม่ได้ปรับแต่งอะไร ปกติจะใช้ crypto.getRandomValues(rnds8) แต่ getRandomValues ไม่ได้ระบุ ปริมาณเอนโทรปีขั้นต่ำ ไว้

    • Hizonner: แทบจะแน่ใจว่าตัวสร้างเลขสุ่มมีอะไรผิดพลาดหนักมาก และน่าจะเป็นปัญหาการจัดการ seed ด้วย มีโอกาสสูงที่มันจะทำให้ระบบเข้ารหัสพังไปด้วย
  • Geee: ตามการตีความกลศาสตร์ควอนตัมแบบหลายโลก จะต้องมีจักรวาลสาขาหนึ่งที่ UUID ทุกตัวเหมือนกันหมด จินตนาการได้เลยว่าคนในโลกนั้นจะคิดยังไง

    • suprjami: พวกเขาคงสร้าง “UUID นั้น” แล้วเติมเลขเพิ่มทีละตัวท้ายสตริงเพื่อให้ไม่ซ้ำ ปัญหาจบ
    • BobaFloutist: ไม่ใช่แค่นั้น ยังต้องมีจักรวาลที่ทุกอย่างเหมือนกันเกือบหมด ต่างกันแค่ UUID ตัวเดียวที่ไม่ซ้ำด้วย เพียงแต่พวกเขายังใช้มันไม่ได้ หรืออาจมีจักรวาลที่ UUID สองตัวแรกเท่านั้นที่ไม่ซ้ำ หลังจากนั้นทุก UUID มีแค่สองค่านั้น
    • nyantaro1: นี่แหละเหตุผลที่ผมไม่ค่อยชอบแนว Everett
  • mittermayr: เห็นด้วยเต็มที่ว่ามันฟังไม่สมเหตุสมผล แต่ถ้าจะเดา ผมคิดถึงความต่างว่าเมื่อก่อนสร้าง UUIDv4 บนมือถือของผู้ใช้แล้วส่งเข้า DB แต่ UUID ที่ชนกันวันนี้ถูกสร้างบนเซิร์ฟเวอร์ Ubuntu
    ผมไม่แน่ใจว่า UUIDv4 สร้างอย่างไร หรือคุณลักษณะของเครื่องที่สร้างมีผลต่ออัลกอริทึมหรือไม่ แต่ความเปลี่ยนแปลงเดียวที่นึกออกคือ เมื่อก่อนสร้างบนอุปกรณ์ และเพิ่งย้ายมาสร้างบนเซิร์ฟเวอร์เมื่อไม่กี่เดือนก่อน

    • AntiUSAbah: หมายถึงให้ผู้ใช้สร้าง UUID เองเหรอ? พูดตรง ๆ ผมว่ามีโอกาสสูงกว่ามากที่มันเป็น implementation แปลก ๆ มากกว่าจะเป็น UUID collision จริง อยากรู้ว่า DB แสดง collision นั้นออกมายังไง
    • wongarsu: ถ้าทั้งสอง UUID ถูกสร้างจากอุปกรณ์ ก็พอเข้าใจโอกาสชนได้ เคยมีกรณีที่เครื่องปลายทางราคาถูก seed ตัวสร้างเลขสุ่มไม่ดีพอจนค่าที่ดู “สุ่ม” ชนกัน และถ้าไลบรารีใช้ RNG ราคาถูกแทน cryptographic RNG ที่เหมาะสมก็ยิ่งแย่
      แต่ถ้าเป็นฝั่งเซิร์ฟเวอร์ โดยเฉพาะในปี 2026 ก็ไม่ควรเป็นแบบนั้น ในอดีต VM random seed เคยเป็นปัญหา แต่ทุกวันนี้ควรน้อยลงมาก ถึง UUID ฝั่งหนึ่งจะถูกสร้างมาแย่ แต่ถ้าอีกฝั่งสุ่มจริง โอกาสจะชนกันก็ยังต่ำมาก เพราะฉะนั้นน่าจะต้องมีปัญหาทั้งสองฝั่ง
    • stubish: UUIDv4 collision มีโอกาสต่ำอย่างสุดขั้ว ในทางสถิติสาเหตุที่น่าเชื่อกว่าคือสองระบบใช้ seed เดียวกัน ถ้า seed มีแค่ไม่กี่ไบต์ โอกาสชนอาจเพิ่มจากระดับหนึ่งในหลายพันล้าน ไปเป็นหนึ่งในหลายล้านได้เลย
  • dweez: ได้เวลากลับมาอ่านบทความสนุกชิ้นนี้อีกครั้ง: https://jasonfantl.com/posts/Universal-Unique-IDs/
    ถ้าเปลี่ยนทั้งจักรวาลเป็นคอมพิวเตอร์ยักษ์แล้วสร้างแต่ UUID ไปจนถึงภาวะ heat death ของเอกภพ จะต้องใช้ ID space กี่บิต?

    • CodeWriter23: ถ้าจะไปถึงขั้นนั้น อันนี้ก็ต้องไม่พลาด: https://www.decisionproblem.com/paperclips/
    • ipaddr: ตัวอย่างทำนอง “ตอนนี้คุณกังวลไหมว่ามนุษย์ทุกคนบนโลกจะโดนอุกกาบาต” อาจไม่ค่อยดีนัก เพราะอุกกาบาตลูกเดียวก็อาจจบโลกได้ และถ้าให้เวลามากพอ ความเป็นไปได้นั้นก็สูงขึ้น
  • beejiu: อยากรู้ว่า UUID ถูกสร้างฝั่งไคลเอนต์หรือฝั่งเซิร์ฟเวอร์ ถ้าฝั่งไคลเอนต์อาจเป็นเพราะ crawler bot ก็ได้ เช่น Googlebot รัน JavaScript ด้วย “ความสุ่ม” แบบกำหนดแน่นอน

    • adzm: ในเหตุการณ์ก่อนหน้าของแพ็กเกจนั้น ข้อสรุปก็คือ Googlebot มีความสุ่มไม่เพียงพอ: https://github.com/uuidjs/uuid/issues/546
    • AgentME: แทบจะแน่นอนว่าเป็นกรณีนี้ หรือไม่ก็ใช้แพ็กเกจเวอร์ชันเก่าที่ใช้ system RNG ไม่ถูกต้อง หรือโหลด polyfill เก่าพัง ๆ ที่ไป reimplement JS crypto API หรือเป็นโฮสติ้งแปลก ๆ ที่ resume VM snapshot เดียวกันบนหลายเซิร์ฟเวอร์จน random state ถูกคัดลอก
      คำอธิบายแนวนี้สมเหตุสมผลกว่าการชนกันแบบสุ่มจริงอยู่หลายลำดับขั้น
  • merlindru: มีโอกาสสูงว่าเป็นปัญหาเรื่อง seed ถ้าพิสูจน์ได้ว่าไม่ใช่ คุณอาจดังขึ้นมานิดหน่อยก็ได้

  • erlkonig: ผมพูดกับทีมมาตลอดว่าถ้าข้อมูลมากพอ ค่าสุ่มก็มีวันชนกันได้ และตอนนั้นเราจะได้เห็นว่าซอฟต์แวร์แข็งแรงแค่ไหน
    ถึงอย่างนั้นก็ยังมีนักพัฒนามากประสบการณ์ หัวหน้าทีม หรือ CIO จำนวนมากที่เชื่อว่ามันเป็นไปไม่ได้ แล้วไม่เขียนโค้ดรับมือกรณีนั้นเลย พอเป็นอย่างนี้ RNG ที่ไม่ดีก็พังระบบได้เร็วกว่าที่คาดมาก และอาจทำให้เสียหายพร้อมกันโดยไม่มีการตรวจจับหรือสร้างใหม่ ฟังดูคล้ายคนประเภทที่ไม่เช็กว่า malloc() สำเร็จหรือไม่ ผมชอบถามกลับว่า “ถ้ามันเป็นไปไม่ได้จริง เราใช้บิตเยอะเกินไปหรือเปล่า?”

  • leni536: มันไม่น่าใช่เรื่องบังเอิญ แต่มีบั๊กอยู่ที่ไหนสักแห่ง ดูคร่าว ๆ แล้วแพ็กเกจน่าจะเรียก crypto.randomUUID() ของ JS runtime และตัวนี้ควร seed มาอย่างถูกต้องเสมอ
    โอกาสที่ตัว runtime จะมีบั๊กก็ดูต่ำมาก แต่ก็ไม่แน่ อยากรู้ว่าใช้ JS runtime ตัวไหน

  • jbverschoor: สาเหตุที่ฟังดูเป็นไปได้ที่สุดคือแพ็กเกจ random generation ที่ uuid พึ่งพาอยู่เพิ่งถูก compromise จนทำให้เลข “สุ่ม” กลายเป็นสิ่งที่คาดเดาได้ ผลลัพธ์คืออาจมี supply chain attack ที่ทำให้โปรเจกต์ด้านการเข้ารหัส SSL และการเงินจำนวนมากเสี่ยงไปด้วย

    • jbverschoor: ใน uuid/src/rng.ts ที่เปลี่ยนเมื่อ 3 สัปดาห์ก่อน มีการเปลี่ยนอาร์เรย์สุ่มให้เป็น const ทำให้ทุกการเรียกใช้แชร์อาร์เรย์สุ่มชุดเดียวกัน
      จากนั้นการเรียกถัดไปก็ไปอัปเดตรหัสสุ่มเดิม ดังนั้นถ้าคุณใช้มันสร้างอะไรสำคัญก็ขอให้โชคดี โค้ดเก่าใช้ slice() เพื่อทำสำเนาใหม่ อาจเป็นการเปลี่ยนโดยไม่ตั้งใจ แต่ผมไม่เข้าใจว่ามันหลุดมาได้ยังไง ทั้งที่ดูเหมือนแม้แต่เทสต์ที่สร้างเลขสุ่มสองตัวแล้วเช็กว่าไม่เหมือนกันก็น่าจะไม่ผ่าน
  • pif: ต่อให้มีแหล่งเอนโทรปีคุณภาพสูง ก็ไม่สามารถเปลี่ยนคำว่า “น่าจะเป็น” ให้กลายเป็น “รับประกันแน่นอน” ได้ ถ้าคุณต้องการค่าที่เดายาก ให้ไปหาวิธีทางคริปโต แต่ถ้าต้องการ ความไม่ซ้ำที่รับประกันได้ คุณต้องสร้างมันเอง

  • athrowaway3z: กฎคร่าว ๆ ง่าย ๆ คือให้คิดว่าคุณสามารถใส่ timestamp ลงไปใน ID นอกเหนือจากค่าที่สุ่มได้หรือไม่ ซึ่งส่วนใหญ่คำตอบคือได้ และ UUIDv7 ก็มักพอ
    ถ้าคุณตรวจสอบปัญหานี้ลึกจนเขียนพิสูจน์ได้เองว่าการรั่วไหลของข้อมูลรับได้ไม่ได้ ก็ขอแสดงความยินดี ระบบนั้นน่าจะซับซ้อนและช้าพอที่จะใช้ strong cryptographic hash หรือถ้าขี้เกียจก็ใช้ UUIDv5 ได้

  • darqis: PostgreSQL 18 รองรับ uuidv7 แบบเนทีฟแล้ว และตั้งค่า default เป็น unique กับ uuid7() ได้เลย

  • tumdum_: เป็นตัวสร้างเลขสุ่มเทียมที่มี seed แย่

  • serf: โอกาสระดับ 4.72 × 10²⁸ ต่อ 1 หรือประมาณ 47.3 octillion ต่อ 1 ถ้าเป็นเรื่องจริง ผมจะสงสัย race condition หรือความผิดพลาดง่าย ๆ อย่างอื่นก่อน มากกว่าจะไปซื้อลอตเตอรี่

    • petee: ผมกลับคิดตรงข้ามนะ ถ้าคุณโชคดีขนาดนั้นไปแล้ว โอกาสได้โชคอีกก็คงยิ่งน้อยลง เก็บเงินดีกว่า
    • k4rli: เรื่องลอตเตอรี่ไม่สมเหตุสมผล ถ้าเหตุการณ์ที่ไม่น่าเป็นไปได้ระดับนั้นเพิ่งเกิดไป โอกาสที่มันจะเกิดอีกก็ยิ่งต่ำสิ
  • evnix: ต่อให้ไม่พูดถึงคณิตศาสตร์ความน่าจะเป็น โลกจริงที่เราอยู่ก็ทำให้แม้แต่ hardware RNG ที่ดีที่สุดยังสุ่มน้อยกว่าที่คิดได้
    ถ้าไม่ได้เป็นจุดที่ security สำคัญมาก ผมจะย้ายไปใช้พวก TSID หรือ uuidv7 เพื่อทำให้เรื่องแบบนี้แทบไม่เกิดในทางปฏิบัติ ดีกว่าการออกแบบโค้ด retry ให้ซับซ้อนเกินไป

  • jordiburgos: ขออย่าใช้ b6133fd6-70fe-4fe3-bed6-8ca8fc9386cd เลยนะ ผมเช็ก DB ตัวเองแล้ว มันถูกใช้ไปแล้ว

    • rich_sasha: ผมคิดมาตลอดว่าการสร้าง UUID แบบสุ่มนั้นบ้าดี ทุกวันนี้ใช้แต่ LLM แล้ว prompt คือ “สร้าง UUID มา ตรวจสอบว่าไม่เคยมีใครใช้ในโค้ดหรือฐานข้อมูลใด ๆ มาก่อน ทบทวนงานของคุณและคิดอย่างลึกซึ้งในแต่ละขั้นตอน อย่าส่ง reasoning หรือภาษาอังกฤษทั่วไปออกมา ให้ส่งเฉพาะ UUID เองเท่านั้น” ล้อเล่นน่า
    • mittermayr: นั่นไง เราทุกคนได้แต่ UUID เกรดถูก ๆ ส่วน UUID ดี ๆ ถูกเก็บไว้ให้ลูกค้ารายใหญ่
    • robshep: ผมใช้ 16b55183-1697-496e-bc8a-854eb9aae0f3 อยู่ และน่าจะมีอีก ถ้าทุกคนมาโพสต์รายการของตัวเองตรงนี้ เราน่าจะเช็กความซ้ำกันได้ไหม?
  • pyuser583: อยากรู้ว่าทุกวันนี้ UUID แบบไหนเป็นตัวเลือกที่นิยมกว่า

  • smokel: ผมเคยโทษ compiler โทษรังสีคอสมิก โทษ quantum effect หรืออย่างน้อยก็โทษ kernel bug แปลก ๆ ก่อนจะมารู้สุดท้ายว่าตัวเองนี่แหละคือบั๊กอยู่หลายครั้ง
    การชนกันใน 15,000 เรคอร์ด มันไม่น่าเป็นไปได้เกินไป ผมจะสงสัยสาเหตุอื่นก่อน เช่น การจัดการรายการซ้ำ คำขอที่ถูกส่งซ้ำ object ที่ถูกนำกลับมาใช้ใหม่ log ที่ทำให้เข้าใจผิด หรือการนำ identifier จาก code path อื่นกลับมาใช้ ถ้าแชร์โค้ดรอบ ๆ เพิ่มอีกนิด คนอื่นน่าจะช่วยดูได้

  • wazoox: เรื่องนี้ยังไม่เคยเกิดกับผม แต่เมื่อสองวันก่อนผมเพิ่งเจอสิ่งนี้ลึกเข้าไปใน codebase PHP ที่รันอยู่บน production: ฟังก์ชัน createUUID() ที่เอาค่า md5(uniqid('', true)) มาตัดแล้วประกบเป็นหน้าตา UUID
    ไม่รู้เหมือนกันว่าทำไมความสยองแบบนี้ถึงยังไม่กัดจุดตายเรา

  • sedatk: uuidjs/uuid มีคำเตือนว่าอาจสร้าง UUID ซ้ำได้บนไคลเอนต์ที่มี ตัวสร้างเลขสุ่มแบบกำหนดแน่นอน อย่าง Googlebot
    สำหรับแอปที่คาดว่า UUID ที่สร้างฝั่งไคลเอนต์จะต้องไม่ซ้ำเสมอ เรื่องนี้อาจเป็นปัญหา จึงควรมีวิธีตรวจหาค่าซ้ำและล้มเหลวอย่างสวยงาม หรือปิดการเขียนจากไคลเอนต์ Googlebot ไปเลย: https://github.com/uuidjs/uuid/commit/91805f665c38b691ac2cbd...

  • xyzzy123: เคยมีระบบกระจายตัวบน Linux ที่ผมทำ load test อยู่ล้มเหลวเพราะ UUID ซ้ำ
    หลังจากสืบอยู่นานก็พบว่าเป็น kernel bug หรือพูดให้ชัดคือ race condition บนระบบหลายโปรเซสเซอร์ ถ้าสองโปรเซสอ่าน /dev/random พร้อมกันพอดี บางครั้งที่หายากมาก ระดับประมาณหนึ่งในล้าน จะได้ไบต์ชุดเดียวกันกลับมา ผมคงไปดูการ initialize RNG ก่อน

  • baq: เหมือน VM ที่รันอยู่ทำเอนโทรปีหายไปหมดเพราะ virtualization

  • glaslong: คงต้องไปซื้อโคมลาวาสักหน่อยแล้ว

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

  • latentframe: หนึ่งในคำพูดที่อันตรายที่สุดในงานวิศวกรรมคือ เป็นไปไม่ได้ในทางสถิติ เมื่อสเกลใหญ่พอ กรณีสุดโต่งจะไม่ใช่ทฤษฎีอีกต่อไป แต่เป็นเหตุการณ์ใน production

  • 8organicbits: ปีที่แล้วผมเคยเขียนเรื่องนี้ไว้รวมถึง collision จริงและไลบรารีที่เกี่ยวข้อง: https://alexsci.com/blog/uuid-oops/
    UUID จะมีความทนทานต่อการชนกันได้ก็ต่อเมื่อมีข้อจำกัดหลายอย่างที่ต้องปฏิบัติตามอย่างเคร่งครัด และกรณีนี้ก็ดูเหมือนมีแนวโน้มสูงว่าเป็นปัญหาที่ตัวสร้างเลขสุ่ม

  • nu11ptr: สุดท้ายก็เป็นปัญหา แหล่งเอนโทรปี นั่นแหละ เพราะงั้นผมเลยสร้างและ insert ในลูปเสมอ ถ้าเกิดชนกันก็จัดการได้อย่างสวยงาม

  • sbuttgereit: มันไม่ใช่ “เป็นไปไม่ได้ทางเทคนิค” มัน เป็นไปได้ทางเทคนิค มาก ๆ แค่ถ้ามีความสุ่มดีพอ โอกาสจะน้อยมาก ๆ เท่านั้น และ UUIDv4 ก็ไม่ได้มีอะไรที่ป้องกันไม่ให้มันสร้างค่าซ้ำได้ในเชิงเทคนิค

  • beardyw: อาจเป็นคำถามงี่เง่า แต่เราเอาวันที่ต่อท้ายเข้าไปสักหน่อยไม่ได้เหรอ อย่างน้อยเป็นวินาทีในรูปเลขฐานสิบหกก็ยังดี แค่เพิ่มไม่กี่ไบต์ก็น่าจะช่วยรับประกันได้ว่าสิ่งที่โอเควันนี้จะยังโอเคในอนาคต

    • flohofwoe: ใช้ UUID แบบอื่นที่มีข้อมูล timestamp อยู่แล้วก็ได้ เช่น v1 หรือ v7 และยังมีแบบที่ใส่ MAC address ด้วย
    • itsyonas: ใช้ uuidv7 ไปเลย
    • mittermayr: ใช่เลย ข้อมูลกึ่งสุ่มเพิ่มเติมรูปแบบไหนก็น่าจะช่วยป้องกันเรื่องแบบนี้ได้ แต่ก็เหมือนนั่นแหละคือแนวคิดของ UUIDv4 ผมคิดว่ามันมีทั้งความสุ่มและเวลามากพออยู่แล้ว
  • mdavid626: ก็อาจมีคำอธิบายอื่นได้เหมือนกัน เช่น มีใครไปแก้ request ด้วยมือ หรือไปแก้ DB

  • radial_symmetry: ผมก็เคยเจอเรื่องแบบนี้ครั้งหนึ่งจนคิดว่าตัวเองกำลังจะบ้า แต่พอได้อ่านคอมเมนต์พวกนี้ก็โล่งใจขึ้น

  • NKosmatos: มันไม่ใช่ “เป็นไปไม่ได้ทางเทคนิค” ไม่ได้เป็นไปไม่ได้ แค่ ไม่น่าเป็นไปได้มาก ๆ เท่านั้น คงต้องไปซื้อลอตเตอรี่แล้วมั้ง
    ทุกครั้งที่ใช้คำว่า “improbable” ผมจะนึกถึง https://hitchhikers.fandom.com/wiki/Infinite_Improbability_D...

    • sebazzz: จริง ๆ ไม่ควรซื้อลอตเตอรี่ เพราะให้ทั้ง collision นั้นและการถูกรางวัลลอตเตอรี่เกิดขึ้นพร้อมกันยิ่งหายากกว่าอีก
    • rithdmc: เป็นอะไรที่นึกภาพไม่ออกเลยจริง ๆ
  • sudb: ตอนนี้รู้สึกเป็นครั้งแรกว่าการเลือก CUID2 ในโปรเจกต์หนึ่งของผมเป็นความคิดที่ดีจริง ๆ: https://github.com/paralleldrive/cuid2