ไทย

เครื่องมือข้อความและชีวิตประจำวัน · ชุดเครื่องมือข้อความ

อักขระที่มองไม่เห็น: ช่องว่างที่ไม่แยก ตัวเชื่อมที่มีความกว้างเป็นศูนย์ และการตัดแต่ง

· พื้นหลัง

การล้างข้อความ ยูนิโค้ด การเผยแพร่

บรรทัดข้อความที่มองเห็นได้เผยให้เห็นช่องว่างที่ซ่อนอยู่และอักขระ Unicode ที่มีความกว้างเป็นศูนย์
ภาพประกอบเวกเตอร์ต้นฉบับ ToolAcre

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

สองบรรทัดที่เหมือนกันซึ่งไม่ซ้ำกัน - วิธีที่อักขระที่มองไม่เห็นสามารถเอาชนะการขจัดความซ้ำซ้อนและการค้นหาได้อย่างไร

สองบรรทัดอาจดูเหมือนกันในตัวแก้ไข แต่ไม่ผ่านการตรวจสอบความเท่าเทียมกัน การค้นหา หรือการลดความซ้ำซ้อน อันหนึ่งอาจมีช่องว่าง U+0020 ธรรมดา ในขณะที่อีกอันหนึ่งอาจมี U+00A0 ซึ่งเป็นช่องว่างไม่แยก อักขระที่มีความกว้างเป็นศูนย์สามารถสร้างปัญหาเดียวกันได้โดยไม่ต้องใช้ความกว้างที่มองเห็นได้ ทำให้ผู้เผยแพร่มีป้ายกำกับที่ตรงกันสองป้ายที่ยังคงเป็นสตริงที่แตกต่างกัน

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

ที่มา – หน้าเว็บ โปรแกรมประมวลผลคำ ลำดับอิโมจิ และการคัดลอก-วางจาก PDF

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

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

กลุ่มช่องว่าง — พื้นที่ธรรมดา ไม่ขาดตอน แคบและเป็นอุดมคติ และสิ่งที่ JavaScript พิจารณาว่าเป็นช่องว่าง

Unicode มีมากกว่าพื้นที่ในชีวิตประจำวัน U+00A0 คือพื้นที่ไม่แยก U+202F คือพื้นที่แคบที่ไม่แยก และ U+3000 คือพื้นที่ในอุดมคติ JavaScript การจัดการช่องว่างจะรวมอักขระเหล่านี้ไว้ด้วย ดังนั้น `trim()`, `trimStart()` และ `trimEnd()` จึงสามารถลบอักขระเหล่านี้ออกได้เมื่ออักขระเหล่านี้ปรากฏที่ขอบที่เกี่ยวข้องของสตริง

การตัดบรรทัดของ Text Toolkit จะเรียกใช้เมธอด JavaScript เหล่านั้นในแต่ละบรรทัด มันไม่ได้ทำให้ระยะห่างภายในเป็นปกติ ดังนั้นจึงยังคงมีช่องว่างที่ไม่แยกระหว่างคำสองคำ สถิติ "อักขระที่ไม่มีช่องว่าง" จะลบอักขระที่จับคู่ด้วย JavaScript `s` ซึ่งกว้างกว่าช่องว่าง ASCII ใช้ตัวเลขนั้นเป็นการวัดที่กำหนดไว้ ไม่ใช่เป็นการสัญญาว่าจะไม่รวมจุดโค้ดที่มองไม่เห็นทุกจุด

ตระกูลความกว้างเป็นศูนย์ — พื้นที่ความกว้างเป็นศูนย์, ตัวเชื่อมและไม่ใช่ตัวเชื่อม, ตัวเชื่อมคำและเครื่องหมายลำดับไบต์ ซึ่งไม่ใช่ช่องว่างเลย

ตระกูลความกว้างเป็นศูนย์เป็นไปตามกฎที่แตกต่างกัน U+200B พื้นที่ความกว้างเป็นศูนย์, U+200C ไม่ใช่ตัวเชื่อมที่มีความกว้างเป็นศูนย์, U+200D ตัวเชื่อมที่มีความกว้างเป็นศูนย์ และตัวเชื่อมคำ U+2060 มีรูปแบบอักขระมากกว่า JavaScript ช่องว่าง สามัญ `trim()` จึงไม่ลบออก บรรทัดที่มีเครื่องหมายอย่างใดอย่างหนึ่งเหล่านี้ต้องไม่เว้นว่างเพียงเพราะหน้าจอไม่มีหมึก

U+FEFF มีประวัติที่เกี่ยวข้องสองรายการ: ที่จุดเริ่มต้นของข้อมูลที่เข้ารหัส มันสามารถส่งสัญญาณเครื่องหมายลำดับไบต์ ในขณะที่ข้อความจะทำหน้าที่เป็นพื้นที่ไม่แบ่งความกว้างเป็นศูนย์ ECMAScript รวม U+FEFF ในชุดช่องว่างตัดแต่ง ซึ่งแตกต่างจาก U+200B ถึง U+200D การปฏิบัติต่อตระกูลที่มีความกว้างเป็นศูนย์ทั้งหมดเป็นช่องว่างประเภทหนึ่งจึงขัดแย้งกับพฤติกรรม JavaScript ที่เกิดขึ้นจริง

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

จำนวนที่น่าประหลาดใจสามารถแจ้งเตือนคุณถึงเนื้อหาที่ซ่อนอยู่ แต่ไม่สามารถระบุได้ทุกกรณี ToolAcre นับคลัสเตอร์กราฟด้วย `Intl.Segmenter` เมื่อพร้อมใช้งาน ช่างเชื่อมที่มีส่วนร่วมในลำดับอิโมจิอาจช่วยให้จุดโค้ดหลายจุดสร้างกราฟเดียวได้ ดังนั้น การเพิ่มหรือลบมันสามารถเปลี่ยนการเรนเดอร์ได้โดยไม่ต้องสร้างการเพิ่มอักขระตัวเดียวแบบธรรมดาที่ตัวนับจุดโค้ดจะแสดงขึ้นมา

ใช้เบาะแสหลายๆ ข้อร่วมกัน: การจับคู่แบบตรงทั้งหมดล้มเหลว ผลลัพธ์ "ไม่มีการเว้นวรรค" ที่ไม่คาดคิด ข้อความที่คัดลอกได้รับการตรวจสอบในตัวแก้ไขที่รับรู้ Unicode หรือการค้นหา regex สำหรับจุดโค้ดเฉพาะ ตัวนับทางเลือกใช้จุดโค้ดเมื่อ Segmenter ไม่พร้อมใช้งาน ดังนั้นผลลัพธ์อาจแตกต่างกันไปตามความสามารถของเบราว์เซอร์ การนับทำให้การสอบสวนแคบลง ไม่ใช่เครื่องสแกนอักขระที่ซ่อนอยู่หรือโปรแกรมดูชื่อ Unicode

การตรวจจับอักขระที่ซ่อนอยู่: การนับให้เบาะแส ไม่ใช่สินค้าคงคลังที่สมบูรณ์

สำหรับอาร์ติแฟกต์การคัดลอกและวางที่ได้รับการยืนยัน ให้ดำเนินการทำซ้ำและเปิดค้นหาและแทนที่ในโหมด regex การค้นหา `[​]` และการแทนที่ด้วยสิ่งใดจะเป็นการลบช่องว่างความกว้างเป็นศูนย์และอักขระ U+FEFF ที่ฝังไว้ตลอดทั้งข้อความ เครื่องมือจะรวบรวมรูปแบบด้วยแฟล็กส่วนกลางของ JavaScript รายงานจำนวนการแทนที่ และไม่เปลี่ยนแปลงข้อความหากรูปแบบไม่ถูกต้อง

อย่าขยายรูปแบบนั้นโดยอัตโนมัติเป็น `[​-‍]` ช่วงนี้ยังลบ U+200C และ U+200D ซึ่งสามารถเปลี่ยนรูปร่างของสคริปต์และแยกอิโมจิที่รวมเข้าด้วยกันเป็นสัญลักษณ์แยกกัน เพิ่มจุดโค้ดเหล่านั้นเฉพาะเมื่อการตรวจสอบพิสูจน์ได้ว่าไม่พึงประสงค์เท่านั้น หลังจากเปลี่ยนแล้ว ให้ดำเนินการขจัดข้อมูลซ้ำซ้อนและเปรียบเทียบเอาต์พุตกับต้นฉบับที่เก็บรักษาไว้ก่อนที่จะเผยแพร่

ตัวอย่างการทำงาน: ลบเฉพาะอักขระที่มีความกว้างเป็นศูนย์ที่ได้รับการยืนยันแล้วก่อนที่จะยกเลิกการทำซ้ำ

การล้างข้อมูลนี้ไม่ได้ระบุถึงอักขระควบคุมแบบสองทิศทาง โฮโมกลิฟ หรือปัญหาด้านความปลอดภัยทุกประการที่เกี่ยวข้องกับข้อความที่ทำให้เกิดความสับสน เครื่องหมายบอกทิศทางสามารถเปลี่ยนลำดับการมองเห็นได้ ในขณะที่การโจมตีแบบโฮโมกลิฟใช้อักขระที่มองเห็นได้ต่างกันซึ่งคล้ายคลึงกัน ทั้งสองปัญหาไม่ได้รับการแก้ไขด้วยการลบช่องว่าง และ regex อักขระที่มองไม่เห็นโดยไม่เลือกปฏิบัติสามารถสร้างความเสียหายให้กับเนื้อหาหลายภาษาที่ถูกต้องตามกฎหมายในขณะที่พลาดความเสี่ยงที่แท้จริง

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

สิ่งที่นำติดตัวไป — มองไม่เห็นไม่ได้หมายความว่าไม่เป็นอันตราย ตัวนับของ Text Toolkit และ regex ค้นหาและแทนที่เปิดเผยและลบออกโดยไม่ต้องออกจากเบราว์เซอร์

ล่องหนไม่ได้หมายความว่าว่างเปล่า ใช้แทนกันได้ หรือเป็นอันตราย ช่องว่างที่ไม่แยกเป็นช่องว่างที่มีความหมายโครงร่าง ตัวเชื่อมที่มีความกว้างเป็นศูนย์สามารถดำเนินซีแมนทิกส์การจัดรูปแบบได้ U+FEFF ทำงานแตกต่างออกไปอีกครั้งภายใต้ JavaScript การตัดแต่ง การล้างข้อมูลที่แม่นยำเริ่มต้นด้วยการตั้งชื่อจุดโค้ด ทำความเข้าใจว่าเหตุใดจึงอาจมีอยู่ และตัดสินใจว่าปลายทางยังต้องการฟังก์ชันหรือไม่

ใช้ชุดเครื่องมือข้อความเป็นเวิร์กเบนช์ฝั่งเบราว์เซอร์ที่มีการควบคุม: การนับอาจทำให้เกิดความคลาดเคลื่อน การค้นหาและแทนที่ regex สามารถลบชุดที่กำหนดไว้อย่างแม่นยำออก และการขจัดความซ้ำซ้อนสามารถยืนยันได้ว่าความแตกต่างที่ซ่อนอยู่นั้นหายไปแล้ว รักษาต้นฉบับ หลีกเลี่ยงการลบตัวเชื่อมตามค่าเริ่มต้น และตรวจสอบผลลัพธ์ที่แสดงผล การแก้ไขที่แคบและตรวจสอบได้นั้นปลอดภัยกว่าการใช้ Unicode ที่มองไม่เห็นทั้งหมดเป็นเศษซาก