4 คะแนน โดย GN⁺ 2024-01-23 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • สรุปขั้นตอนทีละขั้นสำหรับถอดรหัส QR code ด้วยมือ ตั้งแต่โครงสร้าง โมดูล 21×21 ของเวอร์ชัน 1 ไปจนถึงการถอด mask และแปลงเป็น byte
  • พื้นที่พิเศษ เช่น finder pattern, timing pattern, format information และ quiet zone จำเป็นต่อการรู้จำ แต่ต้องข้ามเมื่ออ่านข้อมูลจริง
  • ข้อมูลจะถูกกู้คืนหลังตรวจสอบ mask pattern และระดับ error correction จาก format information แล้วกลับค่าโมดูลของ QR code ในตำแหน่งที่เป็นโมดูลสีดำของ mask
  • เริ่มจากมุมขวาล่าง อ่านทีละสองคอลัมน์ตาม ลำดับซิกแซก และในโหมด Byte กลุ่ม 8 บิตหลังความยาว 8 บิตจะกลายเป็น byte ของตัวอักษร
  • ไม่จำเป็นต้องแก้ส่วน error correction ด้วยมือ สำหรับ QR code แบบง่าย สามารถถอดรหัสได้โดยอ่าน byte ตามจำนวนที่ฟิลด์ความยาวระบุ แล้วแปลงด้วยตาราง ASCII

เตรียม QR code สำหรับอ่านด้วยมือ

  • QR code สำหรับฝึกสามารถเตรียมได้สามวิธี
    • ป้อนข้อความใดก็ได้เพื่ออัปเดต QR code ที่จะอธิบายด้านล่าง
    • เรียนรู้วิธีอ่านโดยสแกน QR code ที่มีอยู่ด้วยกล้อง
    • ฝึกด้วยคำภาษาอังกฤษแบบสุ่ม โดยคำจะไม่แสดง จึงใช้เป็นแบบฝึกได้
  • QR code ตัวอย่างมีขนาด 21×21 โมดูล
  • หน่วยใน QR code ที่เทียบได้กับพิกเซลเรียกว่า โมดูล (module)
  • ขนาดของ QR code แบ่งตาม เวอร์ชัน (version)
    • เวอร์ชันที่เล็กที่สุดคือ 21×21 โมดูล
    • ในเวอร์ชันถัด ๆ ไป ความยาวด้านหนึ่งจะเพิ่มขึ้นครั้งละ 4
    • QR code ขนาด 21×21 โมดูลคือเวอร์ชัน 1

พื้นที่พิเศษที่ต้องข้ามใน QR code

  • finder pattern ช่วยให้สแกนเนอร์ระบุ QR code ได้ก่อน
  • เส้นว่างรอบ finder pattern ต้องข้ามเมื่ออ่านเนื้อหา
  • QR code เวอร์ชัน 1 ไม่มี alignment pattern
    • alignment pattern เป็นแพตเทิร์นเพิ่มเติมที่ช่วยให้สแกนเนอร์อ่าน QR code ได้ถูกต้อง
  • timing pattern คือสองเส้นที่โมดูลขาวดำสลับกันเสมอ ช่วยให้สแกนเนอร์อ่าน QR code ได้ถูกต้อง
  • format information ใช้กำหนด mask pattern และ ระดับ error correction
    • มี format information แนวตั้งและแนวนอน
    • timing pattern จะตัดผ่านทั้งสองเส้น
  • quiet zone คือขอบสีขาวรอบ QR code
    • ช่วยให้สแกนเนอร์ระบุจุดเริ่มต้นและจุดสิ้นสุดของ QR code

การถอด mask pattern

  • QR code ใช้ mask เพื่อหลีกเลี่ยงกลุ่มสีดำหรือสีขาวขนาดใหญ่
  • mask มีตัวเลือกทั้งหมด 8 แบบ
  • ในตัวอย่าง จะอ่านโมดูลสีดำเป็น 1 และโมดูลสีขาวเป็น 0 เพื่อตรวจสอบบิตของ mask pattern
    • บิตตัวอย่างคือเลขฐานสอง 110
    • 110 เท่ากับเลขฐานสิบ 6
  • mask แต่ละประเภทมีแพตเทิร์นที่กำหนดไว้ล่วงหน้า
  • แพตเทิร์นของ QR code ตัวอย่างดูเหมือน ส่วนหนึ่งของสายรุ้งขาวดำ
  • วาง mask ซ้ำ ๆ บนพื้นที่ข้อมูล แล้วกลับค่าโมดูลของ QR code ทุกตำแหน่งที่เป็นโมดูลสีดำใน mask
  • มี DIY zine ที่รวมชีตสรุปของ mask ทุกประเภทไว้ให้

โหมดการเข้ารหัสและลำดับการอ่าน

  • การถอดรหัสเนื้อหาเริ่มจากการตรวจสอบ โหมดการเข้ารหัส ก่อน
  • ข้อมูลการเข้ารหัสจะอยู่ที่มุมขวาล่างเสมอ
  • ต้องใช้ mask เพื่อถอดข้อมูลโหมดการเข้ารหัสก่อนเช่นกัน
    • ในตัวอย่าง ให้ดูชีตสรุปแล้ว XOR สองช่อง
  • โหมดการเข้ารหัสมี Numeric, Alphanumeric, Byte, ECI, Kanji เป็นต้น
  • โหมดการเข้ารหัสของ QR code ตัวอย่างคือ Byte(4)
  • เนื้อหาเริ่มจากมุมขวาล่าง
    • อ่านขึ้นแบบซิกแซกระหว่างสองคอลัมน์
    • จากนั้นอ่านลงแบบซิกแซกในสองคอลัมน์ถัดไปทางซ้าย
    • ต้องข้ามพื้นที่พิเศษทั้งหมดเสมอ

การถอดรหัสความยาวและ byte

  • 4 บิตแรกคือโหมดการเข้ารหัส
  • ในโหมด Byte 8 บิตถัดไปจะระบุความยาวของเนื้อหา
  • หลังจากนั้น ทุก ๆ 8 บิตจะเป็น byte ของเนื้อหา 1 byte
  • ข้อมูลความยาวก็ต้องใช้ mask เพื่อถอดเช่นกัน
  • ข้อมูลความยาวที่ถอด mask แล้วในตัวอย่างคือ 00001100
    • เป็นเลขฐานสิบ 12
    • หมายความว่าความยาวเนื้อหาทั้งหมดคือ 12 byte
  • byte แรกที่ถอด mask แล้วคือ 01001000
    • เป็นเลขฐานสิบหก 0x48
    • อักขระ ASCII ที่สอดคล้องกันคือ H
  • byte ที่สองที่ถอด mask แล้วคือ 01100101
    • เป็นเลขฐานสิบหก 0x65
    • อักขระ ASCII ที่สอดคล้องกันคือ e
  • byte ที่เหลือถูกเว้นไว้เป็นแบบฝึก และสามารถหยุดได้เมื่ออ่านครบจำนวนอักขระตามที่ฟิลด์ความยาวก่อนหน้าระบุ

ตาราง ASCII และ error correction

  • สามารถใช้ตาราง ASCII เพื่อแปลง ค่าเลขฐานสิบหก เป็นอักขระได้
  • ตัวพิมพ์เล็กเริ่มจาก a ที่ 0x61 และจบที่ z ที่ 0x7A
    • อักขระตรงกลางสามารถนับเพื่อหาได้
  • พื้นที่ที่เหลือทั้งหมดไม่ได้เป็นเนื้อหาเสมอไป
  • QR code ยังมี error correction รวมอยู่ด้วย
    • ช่วยให้อ่าน QR code ได้แม้บางส่วนเสียหาย เบลอ หรือหายไป
    • error correction ถูกสร้างด้วยคณิตศาสตร์ แต่ไม่ครอบคลุมในจุดประสงค์ของการอ่านด้วยมือ
  • หลังจากเรียนรู้ขั้นตอนถอดรหัส QR code แบบง่ายด้วยมือแล้ว สามารถฝึกคำภาษาอังกฤษสั้น ๆ ด้วยปุ่มสุ่มโค้ด หรือสแกน QR code จริงด้วยปุ่ม Scan code ได้
  • ซอร์สโค้ดอยู่ที่ Codeberg
    • ยินดีต้อนรับ PR ที่อธิบายโหมดการเข้ารหัส UTF-8 เป็นพิเศษ

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

 
GN⁺ 2024-01-23
ความคิดเห็นจาก Hacker News
  • ช่วงปลายยุค 90 หรือต้นยุค 2000 ผมอยากย้ายข้อมูลใน ดิสก์ Atari 8-bit ไปไว้บนพีซี
    ผมรู้จักสาย SIO2PC และซอฟต์แวร์ที่ใช้เชื่อมพอร์ต SIO ของ Atari กับพอร์ตอนุกรมของพีซีอยู่แล้ว แต่ตอนนั้นยังไม่มีทักษะอิเล็กทรอนิกส์พอจะทำเอง
    สุดท้ายเลยเขียนโปรแกรม Basic บน Atari ให้อ่านดิสก์ทีละเซกเตอร์ แล้ววาดลงหน้าจอด้วยพิกเซล 4 สีขนาดใหญ่ใน graphics mode 3 จากนั้นต่อ Atari เข้ากับการ์ดทีวีของพีซี แล้วใช้โปรแกรม Delphi จับภาพหน้าจอรัว ๆ เพื่อถอดรหัสข้อมูล
    เพราะเซกเตอร์ว่างทำให้การจัดตำแหน่งพิกเซลเพี้ยน ผมจึงใส่ทั้งแพตเทิร์นมาสก์ เช็กซัม และที่อยู่เซกเตอร์ลงไปด้วย และด้วยวิธีนั้นก็ย้ายข้อมูลทั้งดิสก์ไปยังพีซีได้สำเร็จ
    ทุกวันนี้ผมยังถือว่านี่คือ ความสำเร็จทางวิศวกรรมที่ดีที่สุด ของตัวเอง
    ราว 10 ปีต่อมาผมได้สร้างโปรแกรม SIO2PC ชื่อ AspeQt และฟอร์กจากชุมชนที่ใหม่กว่าชื่อ RespeQt ก็ยังเป็นเครื่องมือที่คนใช้กันมากที่สุดในสายนี้ พร้อมทั้งมีซับฟอรัมเฉพาะบน AtariAge ด้วย: https://forums.atariage.com/forum/184-respeqt-sio2pc-softwar...

    • ทำให้นึกถึงวิธีที่มีการย้อนวิศวกรรม เฟิร์มแวร์และคีย์ของ iPod รุ่นแรก
      ว่ากันว่าใช้ไฟแบ็กไลต์ของ LCD กระพริบเป็นแพตเทิร์นบิต แล้วใช้กล้องอ่านข้อมูลนั้นออกมา: https://mastodon.social/@bagder/111538350617290554
    • ยิ่งระบบที่ล็อกแน่นมีมากขึ้น การ ดึงข้อมูลออกผ่านจอแสดงผล แบบนี้ก็น่าจะมีอนาคตชัดเจน
  • คำอธิบายที่ว่า “การแก้ไขข้อผิดพลาดเป็นคณิตศาสตร์ซับซ้อน เลยไม่สนเวลาจะอ่านด้วยมือ” น่าจะอธิบายเพิ่มอีกหน่อย
    ผมเข้าใจว่าคณิตศาสตร์มันยาก แต่ก็ยังอยากรู้ว่า ข้อมูลสำหรับแก้ไขข้อผิดพลาด ถูกต่อไว้ท้ายข้อมูล ใส่หลังทุกไบต์ หรือแทรกอยู่ตรงกลางกันแน่
    และถ้าเป็น QR code ที่ไม่เสียหายเลย ก็อยากรู้เหมือนกันว่าต่อให้มีการแก้ไขข้อผิดพลาด เราจะยังอ่านด้วยมือได้ไหมโดยข้ามแค่ส่วนคณิตศาสตร์นั้นไป

    • บาร์โค้ดใช้ตัวเลขตัวสุดท้ายเป็น เช็กซัม โดยเอาตัวเลขต่าง ๆ มาบวกคูณแล้วคำนวณแบบ % 10 จนได้ค่า 0 ถึง 9
      เพราะงั้นถึงข้อมูลจะผิด ก็ยังมีโอกาส 1 ใน 10 ที่เช็กซัมจะบังเอิญตรงอยู่ดี และอย่างไรก็ดีตัวเลขตัวสุดท้ายก็ไม่สำคัญต่อ ID บาร์โค้ดสินค้าจริง ๆ
      ครั้งหนึ่งตอนผมจะคืนของที่ Home Depot บาร์โค้ดขาดจนเลขเช็กซัมหลุดหายไป ผมเลยรีบสุดชีวิตเพื่อจะคำนวณมันก่อนที่พนักงานจะค้นหาแบบแมนนวล แต่สุดท้ายพนักงานชนะ และผมก็ยังลืมไม่ลง
      https://www.gs1.org/services/how-calculate-check-digit-manua...
      https://www.simplybarcodes.com/barcode_check_digit_calculato...
    • ข้อมูลใน QR code ถูกเข้ารหัสเป็น สตรีมบิต โดยใช้อักษรชุดใดชุดหนึ่งจากหลายชุด และไบต์ก็เป็นเพียงหนึ่งในนั้น
      จากนั้นจะแบ่งสตรีมบิตออกเป็นบล็อกตามขนาดและระดับการแก้ไขข้อผิดพลาด คำนวณข้อมูลแก้ไขข้อผิดพลาดสำหรับแต่ละบล็อก แล้วนำบล็อกมาอินเตอร์ลีฟ
      เพราะฉะนั้นวิธีนี้จะใช้ไม่ได้กับ QR version 5 ขึ้นไปไม่ว่าระดับการแก้ไขข้อผิดพลาดจะเป็นเท่าไร และใน version 3–5 ก็จะใช้ไม่ได้ถ้าตั้งระดับการแก้ไขข้อผิดพลาดสูง
    • An Artisanal QR Code แสดงวิธีคำนวณเช็กซัมด้วยมือโดยใช้อะริทเมติกที่คล้ายการหารยาว
      ในความเป็นจริง จะมีการใช้โค้ดอยู่สองแบบที่ต่างกันเล็กน้อยคือ Reed-Solomon และ BCH ตามชนิดของข้อมูล
      https://www.quaxio.com/an_artisanal_qr_code.html
  • โพสต์ที่เกี่ยวข้อง:
    Decoding small QR codes by hand (2012) - https://news.ycombinator.com/item?id=36173441 - มิถุนายน 2023, ความคิดเห็น 69 รายการ
    How a QR code works - https://news.ycombinator.com/item?id=32837565 - กันยายน 2022, ความคิดเห็น 114 รายการ
    Creating a QR Code step by step - https://news.ycombinator.com/item?id=24119124 - สิงหาคม 2020, ความคิดเห็น 41 รายการ
    Creating a QR Code step by step - https://news.ycombinator.com/item?id=18360847 - พฤศจิกายน 2018, ความคิดเห็น 34 รายการ

  • ตัวบทความเองก็ดีมากอยู่แล้ว แต่ที่เจ๋งยิ่งกว่าคือมัน สร้างภาพทุกภาพแบบไดนามิก ตามค่าที่ป้อนเข้าไป

  • คำอธิบายวิธีอ่าน QR code นั้นดีมาก และถ้าจะหาอ่านเรื่องการถอดรหัส บาร์โค้ดหนึ่งมิติ ทั่วไปอย่าง UPC บทความนี้ก็ใช้ได้เหมือนกัน:
    https://scanbot.io/blog/how-do-barcodes-work/

  • เมื่อราว 10 ปีก่อนเคยพยายามอ่าน QR code ด้วยตาเปล่า แต่ยอมแพ้เพราะ mask pattern
    ต้องนำ mask pattern มาใช้ด้วย XOR ก่อน แม้กระทั่งก่อนจะรู้ชนิดข้อมูล
    เลยสงสัยว่า mask pattern นี้ช่วยตัวอ่าน QR code จริง ๆ ได้มากแค่ไหน
    เดือนที่แล้วลองหาการตั้งค่า error correction ที่เหมาะที่สุด แต่ถ้าเป็นกรณีที่ไม่เสียหายเลยเหมือนเมทริกซ์สมบูรณ์ที่แสดงบนหน้าจอ คำตอบกลับเป็น “ไม่มี” และกว่าจะได้ข้อสรุปนี้ก็ไม่ง่าย
    หาเอกสารที่เปรียบเทียบการตั้งค่าหลายแบบกับการสแกนหลาย implementation ในสภาพแวดล้อมจริงไม่เจอ เลยลองแสดง QR ขนาดเล็กบนหน้าจอด้วยระดับ error correction ต่างกัน แล้วเขย่ากล้องเพื่อจำลองปัญหาการอ่านเอง แต่ก็ไม่เห็นความแตกต่างที่มีนัยสำคัญระหว่างแต่ละการตั้งค่า
    มีทั้ง alignment marker อย่างน้อย 4 จุด มี margin กว้าง และมี timing pattern ด้วย เลยไม่แน่ใจว่าการไม่มี mask จนเกิดก้อนสีขาวใหญ่ ๆ จะสร้างความต่างได้มากจริงหรือ
    เหตุผลข้อที่สองที่เลิกพยายามอ่าน QR ด้วยตาคือ โดยมากมักมี URL เขียนไว้ด้านล่างเป็นข้อความทางเลือกอยู่แล้ว แม้หลังจากนั้นจะเคยเจอกรณีที่ไม่มีข้อความทางเลือกอยู่บ้าง แต่ก็หายากมาก

    • Error correction เป็นอะไรที่แปลกดี
      ถ้าไม่ใช้ ข้อความจะกินพื้นที่น้อยลงและ QR ก็เล็กลง
      ถ้าต้องให้พอดีกับพื้นที่คงที่ เช่น การพิมพ์สติกเกอร์ ก็สามารถทำให้พิกเซลมีขนาดจริงใหญ่ขึ้นได้ และสำหรับการอ่านให้เสถียร พิกเซลที่ใหญ่ขึ้น ช่วยมากกว่า error correction
      บางครั้งสามารถเพิ่มระดับ error correction ได้โดยไม่ต้องเปลี่ยนขนาด QR สุดท้ายตามความยาวข้อความ ซึ่งในกรณีนั้นก็เหมือนได้ทั้งสองอย่าง
    • Error correction ไม่ได้มีไว้สำหรับคนที่คิดว่า “จะทำให้ข้อความเล็กลงเพื่อให้อ่าน QR code ได้ง่ายขึ้นได้อย่างไร”
      แต่มันมีไว้สำหรับคนที่ยัด URL ทั้งเส้นที่เต็มไปด้วย tracking parameter ลงใน version 25, 117x117 code แล้วเอาไปติดบนป้ายใหญ่ โดยหวังว่าข้อมูลจะยังรอดแม้มีขี้นกตกใส่หรือมีคนแปะสติกเกอร์ทับ
    • ปีที่แล้วเคยทำการทดลองคล้ายกัน และอย่างน้อยสำหรับ 3D printed QR code แบบไม่มี error correction กลับดีที่สุด
      เป็นการทดลองเพื่อดูว่าสามารถพิมพ์ให้เล็กได้แค่ไหนแล้วยังตรวจจับได้อยู่ และก็ดูเหมือนเป็นเพราะพิกเซลแต่ละจุดใหญ่ขึ้นตามที่คอมเมนต์ข้าง ๆ ว่าไว้
  • วิดีโอถอดรหัส QR เมื่อราว 10 ปีก่อน: https://www.youtube.com/watch?v=KA8hDldvfv0 (20 นาที)
    ผมยังมีหน้าเว็บแบบ interactive ที่สร้าง QR code ทีละขั้นตอนด้วย ซึ่งโดยพื้นฐานก็คือกระบวนการย้อนกลับ: https://www.nayuki.io/page/creating-a-qr-code-step-by-step

  • พอเริ่มสนใจเรื่อง error correction ก็พบว่า QR code สามารถออกแบบให้มี สัดส่วนการกู้คืนได้ ตั้งแต่ 7% ถึง 30%
    น่าสนใจดี: https://docs.beaconstac.com/en/articles/6018654-what-is-erro...

    • Error correction เป็นหัวข้อที่น่าสนใจมากจริง ๆ
      Shannon ค้นพบขีดจำกัดเชิงทฤษฎีไว้ตั้งแต่กลางศตวรรษที่ 20 แต่ไม่มีใครรู้ว่าจะไปให้ถึงขีดจำกัดนั้นได้อย่างไร
      พอช่วงทศวรรษ 1990 มีสิทธิบัตร turbo code ที่พาเข้าใกล้ขีดจำกัดนั้นได้อย่างกะทันหัน วงการวิชาการก็ตอบสนองแบบแทบไม่อยากเชื่อ
      และแน่นอนว่าเทคโนโลยีแบบนี้เองที่ทำให้ mobile network ที่เร็วและเชื่อถือได้เกิดขึ้นได้
  • ใน Mystery Hunt 2023 มีปริศนาย่อยข้อหนึ่งที่ต้องถอดรหัส QR ที่พังจนแม้แต่ error correction ก็ช่วยกู้คืนไม่ได้ด้วยมือ
    ผมไล่อ่านคู่มือทั้งหมดที่มีคนพูดถึงในคอมเมนต์นี้แล้ว ซึ่งก็มีประโยชน์ แต่ยังไม่ถึงกับยอดเยี่ยมมาก
    เพราะงั้นการมีบทความละเอียดแบบนี้เพิ่มขึ้นจึงเป็นเรื่องดี และบทความนี้ก็ดูสมบูรณ์มากจริง ๆ
    ถ้าสนใจ ปริศนาอยู่ที่นี่ และส่วนการถอดรหัส QR จะอยู่ช่วงท้าย: https://puzzles.mit.edu/2023/abcde.puzzlefactory.place/puzzl...

  • ดูจาก Wikipedia แล้ว QR code ถูกประดิษฐ์ขึ้นในปี 1994 โดยผู้ผลิตชิ้นส่วนรถยนต์จากญี่ปุ่นเพื่อใช้ติดฉลากชิ้นส่วนรถยนต์
    เลยสงสัยว่าถ้าถูกคิดค้นในวันนี้จะทำให้ดีขึ้นได้ไหม
    จะทำให้เล็กลงกว่านี้ หรืออ่านง่ายกว่านี้ได้หรือเปล่า?

    • ไม่ได้มีอะไรขวางการออกแบบใหม่ที่ดีกว่าอย่างชัดเจน
      ในปี 1994 บาร์โค้ดก็มีอยู่ทุกที่แล้ว แต่ก็ไม่ได้ขัดขวางไม่ให้ QR code ได้รับความนิยม
      หรืออีกทางหนึ่ง อาจแทบไม่มีพื้นที่ให้ปรับปรุงแล้วก็ได้ ถ้าไม่ได้เปลี่ยนแนวคิดไปมากแบบขยับไปใช้ NFC หรืออะไรทำนองนั้น
    • ถ้าถูกคิดค้นวันนี้ มันคงเป็น หกเหลี่ยม