iconv กำลังสร้าง UTF-16 พร้อม BOM


11

ได้รับแรงบันดาลใจจากคำถามนี้ฉันสามารถใช้iconvคำสั่งเพื่อสร้างเอาต์พุต UTF-16 ด้วย BOM และด้วย endianness ที่ระบุได้หรือไม่

iconvข้อความคำสั่งแปลงจากการเข้ารหัสหนึ่งไปยังอีก

ตัวอย่างเช่น:

echo hello | iconv -f ascii -t utf-16

สร้าง UTF-16 "hello\n"เป็นตัวแทนของ

UTF-16 ไฟล์บ่อย แต่ไม่เคยเริ่มต้นด้วยการสั่งซื้อมาร์คไบต์ (BOM) ซึ่งเป็นการเข้ารหัส 2 U+FEFFไบต์ของอักขระ คุณสามารถกำหนด endianness ของไฟล์ UTF-16 กับ BOM โดยการตรวจสอบว่าทั้งสองไบต์แรกหรือFE FFFF FE

iconvคำสั่งมีหลายตัวเลือกสำหรับการสร้าง UTF-16 เอาท์พุท:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

คำสั่งนี้:

echo hello | iconv -f ascii -t utf-16be

สร้าง big-UTF-16 ไม่มี BOM ; ดูเหมือนว่าจะถือว่าถ้าคุณระบุ endianness คุณไม่จำเป็นต้องระบุในเอาท์พุท ในทำนองเดียวกันutf-16leสร้าง UTF-16 แบบ little-endian ที่ไม่มี BOM

นี้:

echo hello | iconv -f ascii -t utf-16

สร้าง (บนระบบ x86 Ubuntu ของฉัน) little-endian UTF-16 พร้อม BOM - แต่ฉันเคยเห็นรายงานของคำสั่งที่คล้ายกันที่สร้าง big-endian UTF-16 ที่มี BOM แม้แต่ในระบบ end-little

ฉันสามารถใช้utf-16beหรือutf-16leเพิ่ม BOM ล่วงหน้าได้ด้วยตนเอง แต่ฉันกำลังมองหาโซลูชันที่เพิ่งใช้iconvคำสั่ง

วิธีแก้ปัญหาอื่นถ้าคุณรู้ว่า endianness -t utf-16สร้างคืออะไร:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

สิ่งที่ฉันต้องการชอบที่จะใช้เป็นสิ่งที่ต้องการ:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

แต่iconvไม่สนับสนุนสิ่งนั้น

แก้ไข:

ใครบางคนที่สามารถเข้าถึงระบบ x86 Mac OSX สามารถโพสต์ความคิดเห็นที่แสดงผลลัพธ์ (คัดลอกและวาง) ของคำสั่งต่อไปนี้ได้หรือไม่?

echo hello | iconv -f ascii -t utf-16 | od -x

1
BOM ลดความสามารถในการพกพาของข้อมูล แต่คุณสามารถเพิ่มได้ด้วยวิธีนี้
RedGrittyBrick

@RedGrittyBrick: มันช่วยลดการพกพาได้อย่างไร (โดยเฉพาะสำหรับ UtF-16) ฉันรู้ว่าฉันสามารถสร้าง BOM ได้อย่างสมบูรณ์ ฉันกำลังมองหาวิธีที่จะทำเช่นนั้นโดยใช้เพียงแค่iconv- และสงสัยว่าทำไม-t utf-16ดูเหมือนว่าจะปล่อยให้ endianness ไม่ได้ระบุ
Keith Thompson

ฉันเดาว่า iconv จะถือว่าเป็นแพลตฟอร์มลำดับไบต์หากคุณไม่ได้ระบุอย่างชัดเจน ในบางแพลตฟอร์มที่ไม่ใช่ windows เครื่องมือประมวลผลข้อความบางอย่างไม่คาดหวัง BOM และทำสิ่งที่ผิด ตัวอย่างอาจเกิดขึ้นเมื่อทำการเชื่อมไฟล์ข้อความหรือใช้เทมเพลตแบบไฟล์เพื่อสร้างเนื้อหา "สำหรับชุดอักขระที่ลงทะเบียนของ IANA UTF-16BE และ UTF-16LE ไม่ควรใช้เครื่องหมายลำดับไบต์เนื่องจากชื่อของชุดอักขระเหล่านี้ได้กำหนดลำดับไบต์ไว้เรียบร้อยแล้ว"
RedGrittyBrick

คำถามนี้แสดงให้เห็นว่าiconv -f UTF-8 -t UTF-16ทำงานในระบบเล็ก ๆ น้อย ๆ (MacOS) ซึ่งสร้าง UTF-16 ขนาดใหญ่ที่มี BOM ซึ่งดูเหมือนว่าแปลกมาก
Keith Thompson

คำตอบ:


9

ไม่ถ้าคุณระบุการเรียงลำดับไบต์iconvห้ามแทรก BOM

นี่คือจากThe Unicode Consortium

ถาม: ฉันควรจัดการกับ BOM อย่างไร

ตอบ: ต่อไปนี้เป็นแนวทางปฏิบัติบางประการ:

  1. โปรโตคอลเฉพาะ (เช่นข้อตกลงของ Microsoft สำหรับไฟล์. txt) อาจต้องใช้ BOM ในสตรีมข้อมูล Unicode บางไฟล์เช่นไฟล์ เมื่อคุณต้องการปฏิบัติตามโปรโตคอลดังกล่าวให้ใช้ BOM
  2. โปรโตคอลบางตัวอนุญาต BOM ที่เป็นตัวเลือกในกรณีของข้อความที่ไม่ได้ติดแท็ก ในกรณีเหล่านั้น
    • ในกรณีที่ทราบว่าสตรีมข้อมูลข้อความเป็นข้อความธรรมดา แต่จากการเข้ารหัสที่ไม่รู้จัก BOM สามารถใช้เป็นลายเซ็นได้ หากไม่มี BOM การเข้ารหัสอาจเป็นอะไรก็ได้
    • ตำแหน่งที่สตรีมข้อมูลข้อความเป็นที่รู้จักกันว่าเป็นข้อความ Unicode ธรรมดา (แต่ไม่ใช่ endian ใด ๆ ) ดังนั้น BOM สามารถใช้เป็นลายเซ็นได้ หากไม่มี BOM ข้อความควรถูกตีความเป็น big-endian
  3. โปรโตคอลแบบไบต์บางตัวคาดหวังอักขระ ASCII ที่จุดเริ่มต้นของไฟล์ หากใช้ UTF-8 กับโปรโตคอลเหล่านี้ควรหลีกเลี่ยงการใช้ BOM เนื่องจากลายเซ็นของฟอร์มการเข้ารหัส
  4. ในกรณีที่ทราบประเภทของสตรีมข้อมูลที่แม่นยำ (เช่น Unicode big-endian หรือ Unicode little-endian) ไม่ควรใช้ BOM โดยเฉพาะอย่างยิ่ง ทุกครั้งที่มีการประกาศสตรีมข้อมูลเป็น UTF-16BE, UTF-16LE, UTF-32BE หรือ UTF-32LE BOM จะต้องไม่ใช้BOM

(ความสำคัญของฉัน)

ฉันคาดหวังว่าiconvจะพยายามซื่อสัตย์ต่อแนวทางสุดท้ายเหล่านี้


ปรับปรุง

พูดนอกเรื่อง

ในความเห็นของฉัน:

  1. ตัวเลือกในการระบุ BOM จะเป็นคุณสมบัติเพิ่มเติมที่เป็นประโยชน์สำหรับ iconv

  2. ไฟล์ UTF-16LE โดยไม่ต้อง BOM คือสามารถใช้งานได้ใน Windows แม้จะมีความพยายามบางครั้ง ตัวอย่างเช่นกล่องโต้ตอบเปิดไฟล์ของ Notepad ช่วยให้คุณสามารถเลือก "Unicode" ซึ่งเป็นชื่อของ Microsoft สำหรับ "UTF-16LE" และ (แปลกใจ) ดูเหมือนว่าจะทำงานกับไฟล์ที่ไม่มี BOM

  3. ฉันสามารถเปิดไฟล์ทดสอบ UTF-16LE (ไม่มี BOM) หรือไฟล์ทดสอบ UTF-8 (ไม่มี BOM) ใน Windows Notepad (XP) ตามปกติเช่นโดยดับเบิลคลิกที่ชื่อไฟล์ใน explorer ดูเหมือนว่าฉันจะใช้งานได้ ฉันรู้ว่าบางครั้ง Windows จะเดาการเข้ารหัสไม่ถูกต้อง - ในกรณีนี้คุณต้องบอกการเข้ารหัส Notepad เมื่อเปิดไฟล์ ความไม่สะดวกนี้หมายถึงการรวม BOM เป็นสิ่งที่ดีกว่าสำหรับไฟล์ข้อความที่มีไว้สำหรับใช้ใน Windows

  4. หากแอปพลิเคชันเฉพาะจะไม่ทำงานกับไฟล์อื่นนอกเหนือจากไฟล์ UTF-16LE กับ BOM ฉันจะยอมรับว่าไฟล์ UTF-16LE ที่ไม่มี BOM นั้นไม่สามารถใช้งานได้สำหรับแอปพลิเคชันเฉพาะนั้น

  5. ฉันสงสัยว่าถ้าคุณสามารถทำให้ทุกอย่างทำงานกับ UTF-8 (โดยไม่มี BOM) นั่นเป็นทางออกที่ดีที่สุดในระยะยาว

อย่างไรก็ตามคำตอบสำหรับคำถาม " ฉันสามารถใช้คำสั่ง iconv เพื่อสร้างเอาต์พุต UTF-16 ด้วย BOM และด้วย endianness ที่ระบุ " ปัจจุบันคือ " ไม่ "


1
และแนวทางแรกคือ A.1? หากฉฉันต้องการที่จะสร้างไฟล์ข้อความ Unicode ที่สามารถใช้งานได้บนระบบ x86 Windows ก็ควรเป็นไฟล์ UTF16 น้อย endian กับ BOM
Keith Thompson

@KeithThompson: ระบบควรยอมรับทั้ง UTF16LE และ UTF16BE อย่างน้อย Windows Notepad ยอมรับทั้งสองอย่างเมื่อมาถึง.txtตราบใดที่ไฟล์มี BOM
user1686

@ KeithThompson: ฉันเห็นด้วยว่าแนวทาง 1 ควรให้ความสำคัญ แต่ iconv ไม่ได้มีวิธีให้คุณระบุ BOM คำตอบสำหรับคำถามเดิมของคุณคือ "ไม่"
RedGrittyBrick

ไม่ใช่คำตอบที่ฉันหวังไว้ แต่เป็นคำตอบและคำตอบที่ละเอียด!
Keith Thompson

2
คำตอบนี้ช่วยฉัน - ช่วยให้ฉันเรียนรู้ว่าทำไมฉันถึงเมา โปรแกรม Windows มาตรฐานเพื่อส่งออก / นำเข้าจากรีจิสทรีC:\Windows\System32\reg.exeส่งออก UTF-16 LE with BOM และจะอ่าน UTF-16 LE with BOM เท่านั้น - จะไม่อ่าน UTF-16 LE โดยไม่มี BOM และจะไม่อ่าน UTF-16 BE กับ BOM - กล่าวอีกอย่างหนึ่งก็คือมันต้องการ BOM เมื่ออ่าน แต่มันน่าจะดีกว่า (โชคดีที่มันอ่าน UTF-8)
davidbak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.