มีอะไรที่แตกต่างกันระหว่าง UTF-8 และ UTF-8 โดยไม่ต้องBOM ? ไหนดีกว่ากัน
มีอะไรที่แตกต่างกันระหว่าง UTF-8 และ UTF-8 โดยไม่ต้องBOM ? ไหนดีกว่ากัน
คำตอบ:
UTF-8 BOM เป็นลำดับของไบต์ที่จุดเริ่มต้นของสตรีมข้อความ ( 0xEF, 0xBB, 0xBF
) ที่ช่วยให้ผู้อ่านเดาไฟล์ได้อย่างน่าเชื่อถือมากขึ้นว่าเข้ารหัสใน UTF-8
โดยปกติBOMจะใช้เพื่อส่งสัญญาณความเป็นendiannessของการเข้ารหัส แต่เนื่องจาก endianness นั้นไม่เกี่ยวข้องกับ UTF-8 จึงไม่จำเป็นต้องใช้ BOM
ตามที่มาตรฐาน Unicodeที่BOM สำหรับไฟล์ UTF-8 จะไม่แนะนำ :
2.6 แผนการเข้ารหัส
... ไม่จำเป็นต้องใช้ BOM หรือแนะนำสำหรับ UTF-8 แต่อาจพบในบริบทที่ข้อมูล UTF-8 ถูกแปลงจากรูปแบบการเข้ารหัสอื่น ๆ ที่ใช้ BOM หรือที่ BOM ใช้เป็นลายเซ็น UTF-8 . ดูส่วนย่อย“ Byte Order Mark” ในส่วน 16.8 พิเศษสำหรับข้อมูลเพิ่มเติม
คำตอบที่ยอดเยี่ยมอื่น ๆ ตอบแล้วว่า:
EF BB BF
แต่เนื่องจากข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ BOM สำหรับ UTF-8 อาจเป็นวิธีที่ดีในการ "ดม" ถ้าสตริงถูกเข้ารหัสใน UTF-8 ... หรืออาจเป็นสตริงที่ถูกต้องในการเข้ารหัสอื่น ๆ ...
ตัวอย่างเช่นข้อมูล [EF BB BF 41 42 43] อาจเป็น:
ดังนั้นในขณะที่การรู้จำการเข้ารหัสของเนื้อหาไฟล์นั้นทำได้อย่างยอดเยี่ยมโดยดูที่ไบต์แรก แต่คุณไม่ควรเชื่อถือสิ่งนี้ดังที่แสดงในตัวอย่างด้านบน
การเข้ารหัสควรเป็นที่รู้จักไม่ใช่การทำนาย
มีปัญหาอย่างน้อยสามข้อในการใส่ BOM ในไฟล์ที่เข้ารหัส UTF-8
และอย่างที่คนอื่น ๆ พูดถึงมันไม่เพียงพอหรือไม่จำเป็นที่จะต้องมี BOM เพื่อตรวจสอบว่ามีบางอย่างที่เป็น UTF-8:
cat
จะไม่ให้ผลลัพธ์ที่สะอาดผลลัพธ์ที่มี BOM ในช่วงเริ่มต้นเท่านั้น ถ้าคุณหมายถึงอย่างนั้นนั่นเป็นเพราะการcat
ทำงานในระดับไบต์ไม่ใช่ระดับเนื้อหาที่ถูกตีความและในทำนองเดียวกันcat
ไม่สามารถจัดการภาพถ่ายได้ ถึงกระนั้นมันก็ไม่ได้ทำอันตรายอะไรมากมาย นั่นเป็นเพราะ BOM เข้ารหัสพื้นที่ไม่ทำลายความกว้างเป็นศูนย์
นี่คือตัวอย่างของการใช้ BOM ที่ทำให้เกิดปัญหาจริงและยังมีอีกหลายคนที่ไม่รู้
สคริปต์ Shell, สคริปต์ Perl, สคริปต์ Python, สคริปต์ Ruby, สคริปต์ Node.js หรือปฏิบัติการอื่นใดที่จำเป็นต้องเรียกใช้โดยล่าม - เริ่มต้นด้วยบรรทัด shebangซึ่งมีลักษณะดังนี้:
#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node
มันบอกระบบที่ต้องใช้ล่ามเมื่อเรียกใช้สคริปต์ดังกล่าว หากสคริปต์ถูกเข้ารหัสใน UTF-8 อาจมีการล่อลวงให้รวม BOM ตั้งแต่เริ่มต้น แต่จริงๆแล้ว "#!" ตัวละครไม่ได้เป็นเพียงตัวละคร ในความเป็นจริงแล้วพวกเขาเป็นเลขอาถรรพ์ที่ประกอบด้วยตัวละคร ASCII สองตัว หากคุณใส่บางสิ่ง (เช่น BOM) ไว้หน้าอักขระเหล่านั้นไฟล์จะดูเหมือนว่ามีหมายเลขเวทย์มนตร์แตกต่างกันและอาจนำไปสู่ปัญหาได้
ดู Wikipedia, บทความ: Shebang, หมวด: Magic number :
อักขระ shebang นั้นมีสองไบต์เดียวกันในการเข้ารหัส ASCII แบบขยายรวมถึง UTF-8 ซึ่งโดยทั่วไปจะใช้สำหรับสคริปต์และไฟล์ข้อความอื่น ๆ บนระบบ Unix ที่คล้ายกันในปัจจุบัน อย่างไรก็ตามไฟล์ UTF-8 อาจเริ่มต้นด้วยเครื่องหมายสั่งทางเลือก (BOM); หากฟังก์ชั่น "exec" ตรวจพบไบต์ 0x23 และ 0x21 โดยเฉพาะการแสดงตนของ BOM (0xEF 0xBB 0xBF) ก่อนที่ shebang จะป้องกันไม่ให้ล่ามสคริปต์ทำงานผู้มีอำนาจบางคนแนะนำให้ต่อต้านการใช้เครื่องหมายคำสั่งไบต์ในสคริปต์ POSIX (เหมือน Unix), [14] ด้วยเหตุผลนี้และสำหรับการทำงานร่วมกันที่กว้างขึ้นและข้อกังวลทางปรัชญา นอกจากนี้ไม่จำเป็นต้องใช้เครื่องหมายคำสั่งไบต์ใน UTF-8 เนื่องจากการเข้ารหัสนั้นไม่มีปัญหาเรื่องความเอนเอียง มันทำหน้าที่เพียงเพื่อระบุการเข้ารหัสเป็น UTF-8 [เน้นเพิ่ม]
การนำไปใช้งานต้องไม่เพิ่มเครื่องหมายคำสั่งไบต์ไปยังจุดเริ่มต้นของข้อความ JSON
ไม่เพียง แต่เป็นสิ่งผิดกฎหมายใน JSON เท่านั้นยังไม่จำเป็นต้องพิจารณาการเข้ารหัสอักขระเนื่องจากมีวิธีที่เชื่อถือได้มากกว่าในการกำหนดการเข้ารหัสอักขระและ endianness ที่ใช้ในสตรีม JSON ใด ๆ อย่างไม่น่าสงสัย (ดูคำตอบนี้สำหรับรายละเอียด)
ไม่เพียง แต่เป็นสิ่งผิดกฎหมายใน JSON และไม่จำเป็นแต่อย่างใดมันแตกซอฟต์แวร์ทั้งหมดที่กำหนดการเข้ารหัสโดยใช้วิธีการนำเสนอในRFC 4627 :
การพิจารณาการเข้ารหัสและ endianness ของ JSON ตรวจสอบสี่ไบต์แรกสำหรับไบต์ NUL:
00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8
ตอนนี้ถ้าไฟล์เริ่มต้นด้วย BOM มันจะมีลักษณะดังนี้:
00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8
โปรดทราบว่า:
ทั้งหมดอาจถูกตีความอย่างไม่ถูกต้องว่าเป็น UTF-8 และตีความผิดหรือปฏิเสธว่าเป็น UTF-8 ที่ไม่ถูกต้องหรือไม่ได้รับการยอมรับ
นอกจากนี้หากการทดสอบการใช้งานสำหรับ JSON ที่ถูกต้องตามที่ฉันแนะนำมันจะปฏิเสธแม้กระทั่งอินพุตที่เข้ารหัสแน่นอนเป็น UTF-8 เพราะมันไม่ได้ขึ้นต้นด้วยอักขระ ASCII <128 เท่าที่ควรเป็นไปตาม RFC
ไม่จำเป็นต้องใช้ BOM ใน JSON ถือเป็นการกระทำที่ผิดกฎหมายและทำลายซอฟต์แวร์ที่ทำงานอย่างถูกต้องตาม RFC มันควรจะเป็นผู้ดีที่ไม่ใช้แล้วและยังมีคนที่ยืนยันในการทำลาย JSON โดยใช้ BOM ความคิดเห็นกฎการอ้างอิงที่แตกต่างกันหรือประเภทข้อมูลที่แตกต่างกันเสมอ แน่นอนว่าทุกคนมีอิสระที่จะใช้สิ่งต่าง ๆ เช่น BOM หรืออะไรก็ได้ถ้าคุณต้องการ - อย่าเรียกมันว่า JSON
สำหรับรูปแบบข้อมูลอื่นที่ไม่ใช่ JSON ลองดูว่ามันมีลักษณะอย่างไร หากการเข้ารหัสเพียงอย่างเดียวคือ UTF- * และอักขระตัวแรกจะต้องเป็นอักขระ ASCII ที่ต่ำกว่า 128 ดังนั้นคุณจึงมีข้อมูลทั้งหมดที่จำเป็นในการพิจารณาการเข้ารหัสและความสิ้นสุดของข้อมูลของคุณ การเพิ่ม BOMs แม้จะเป็นคุณลักษณะเสริมจะทำให้ซับซ้อนและเกิดข้อผิดพลาดได้ง่ายขึ้นเท่านั้น
สำหรับการใช้นอก JSON หรือสคริปต์ฉันคิดว่ามีคำตอบที่ดีอยู่แล้วที่นี่ ฉันต้องการเพิ่มข้อมูลรายละเอียดเพิ่มเติมเกี่ยวกับการเขียนสคริปต์และการทำให้เป็นอนุกรมเนื่องจากเป็นตัวอย่างของอักขระ BOM ที่ทำให้เกิดปัญหาจริง
อะไรคือความแตกต่างระหว่าง UTF-8 และ UTF-8 ที่ไม่มี BOM
คำตอบสั้น ๆ : ใน UTF-8 BOM จะถูกเข้ารหัสเป็นไบต์EF BB BF
ที่จุดเริ่มต้นของไฟล์
คำตอบยาว:
เริ่มแรกคาดว่าUnicodeจะถูกเข้ารหัสใน UTF-16 / UCS-2 BOM ได้รับการออกแบบสำหรับรูปแบบการเข้ารหัสนี้ เมื่อคุณมีหน่วยรหัส 2 ไบต์คุณจำเป็นต้องระบุลำดับที่สองไบต์นั้นและแบบแผนทั่วไปสำหรับการทำเช่นนี้คือการรวมอักขระ U + FEFF เป็น "เครื่องหมายคำสั่งซื้อ Byte" ที่จุดเริ่มต้นของข้อมูล อักขระ U + FFFE ถูกยกเลิกการกำหนดอย่างถาวรเพื่อให้สามารถใช้การตรวจสอบลำดับไบต์ที่ไม่ถูกต้องได้
UTF-8 มีลำดับไบต์เดียวกันโดยไม่คำนึงถึงแพลตฟอร์ม endianness ดังนั้นจึงไม่จำเป็นต้องมีเครื่องหมายใบสั่งไบต์ อย่างไรก็ตามอาจเกิดขึ้น (ตามลำดับไบต์EF BB FF
) ในข้อมูลที่ถูกแปลงเป็น UTF-8 จาก UTF-16 หรือเป็น "ลายเซ็น" เพื่อระบุว่าข้อมูลนั้นเป็น UTF-8
ไหนดีกว่ากัน
ไม่มี ตามที่ Cote มาร์ตินตอบมาตรฐาน Unicode ไม่แนะนำ มันทำให้เกิดปัญหากับซอฟต์แวร์ที่ไม่ใช่ BOM
วิธีที่ดีกว่าในการตรวจสอบว่าไฟล์เป็น UTF-8 คือการตรวจสอบความถูกต้องหรือไม่ UTF-8 มีกฎที่เข้มงวดเกี่ยวกับลำดับของไบต์ที่ถูกต้องดังนั้นความน่าจะเป็นของการบวกที่ผิดพลาดจึงไม่มีความสำคัญ หากลำดับไบต์ดูเหมือนว่า UTF-8 ก็น่าจะเป็น
sh
, perl
, g++
และเครื่องมือฟรีและมีประสิทธิภาพอื่น ๆ อีกมากมาย ต้องการทำงานหรือไม่ เพียงซื้อรุ่น MS MS สร้างปัญหาเฉพาะแพลตฟอร์มเช่นเดียวกับความเสียหายของช่วง \ x80- \ x95
ระบุ UTF-8 พร้อม BOM ได้ดีกว่า ฉันได้มาถึงข้อสรุปนี้อย่างหนัก ฉันกำลังทำงานในโครงการที่ผลลัพธ์อย่างใดอย่างหนึ่งคือไฟล์ CSVรวมถึงอักขระ Unicode
หากไฟล์ CSV ถูกบันทึกโดยไม่มี BOM Excel จะคิดว่าเป็น ANSI และแสดงซึ่งพูดไม่ชัด เมื่อคุณเพิ่ม "EF BB BF" ที่ด้านหน้า (ตัวอย่างเช่นโดยบันทึกอีกครั้งโดยใช้ Notepad ด้วย UTF-8 หรือ Notepad ++ กับ UTF-8 พร้อม BOM) Excel จะเปิดได้ดี
แนะนำให้ใช้การเตรียมอักขระ BOM เป็นไฟล์ข้อความ Unicode โดย RFC 3629: "UTF-8 ซึ่งเป็นรูปแบบการแปลง ISO 10646", พฤศจิกายน 2546 ที่http://tools.ietf.org/html/rfc3629 (ข้อมูลล่าสุดนี้อยู่ที่: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html )
BOM มีแนวโน้มที่จะบูม (ไม่มีการเล่นสำนวนเจตนา (sic)) บางแห่ง และเมื่อมันบูม (ตัวอย่างเช่นไม่ได้รับการยอมรับจากเบราว์เซอร์บรรณาธิการ ฯลฯ ) มันจะปรากฏเป็นตัวอักษรแปลก ๆ
ที่จุดเริ่มต้นของเอกสาร (เช่นไฟล์ HTML, การตอบสนองJSON , RSS , ฯลฯ ) และทำให้เกิดชนิดของ embarrassments เช่นนั้นปัญหาการเข้ารหัสที่ผ่านมามีประสบการณ์ในช่วงการพูดคุยของโอบามาบน Twitter
มันน่ารำคาญมากเมื่อมันปรากฏขึ้นในสถานที่ยากต่อการดีบักหรือเมื่อการทดสอบถูกละเลย ดังนั้นจึงเป็นการดีที่สุดที่จะหลีกเลี่ยงมันเว้นแต่คุณจะต้องใช้มัน
คำถาม: UTF-8 กับ UTF-8 ต่างกันอย่างไรถ้าไม่มี BOM ไหนดีกว่ากัน
นี่คือข้อความที่ตัดตอนมาจากบทความ Wikipedia บนเครื่องหมายคำสั่งซื้อ (BOM)ที่ฉันเชื่อว่าให้คำตอบที่ดีสำหรับคำถามนี้
เกี่ยวกับความหมายของ BOM และ UTF-8:
มาตรฐาน Unicode อนุญาตให้BOMในUTF-8แต่ไม่จำเป็นต้องมีหรือแนะนำการใช้งาน ลำดับไบต์ไม่มีความหมายใน UTF-8 ดังนั้นการใช้งานใน UTF-8 เพียงอย่างเดียวคือการส่งสัญญาณเมื่อเริ่มต้นที่สตรีมข้อความถูกเข้ารหัสใน UTF-8
อาร์กิวเมนต์ที่ ไม่ ใช้ BOM:
แรงจูงใจหลักสำหรับการไม่ใช้ BOM คือความเข้ากันได้ย้อนหลังกับซอฟต์แวร์ที่ไม่ได้รับการ Unicode ... แรงจูงใจอีกอย่างสำหรับการไม่ใช้ BOM คือการสนับสนุน UTF-8 ว่าเป็นการเข้ารหัส "ค่าเริ่มต้น"
อาร์กิวเมนต์ สำหรับการ ใช้ BOM:
อาร์กิวเมนต์สำหรับการใช้ BOM นั้นไม่จำเป็นต้องมีการวิเคราะห์แบบฮิวริสติกเพื่อกำหนดตัวอักษรที่เข้ารหัสไฟล์ การวิเคราะห์ในอดีตเพื่อแยกความแตกต่างการเข้ารหัส 8 บิตต่าง ๆ มีความซับซ้อนผิดพลาดง่ายและบางครั้งช้า มีไลบรารีจำนวนมากที่ช่วยให้งานง่ายขึ้นเช่น Mozilla Universal Charset Detector และ International Components for Unicode
โปรแกรมเมอร์สันนิษฐานว่าการตรวจจับ UTF-8 นั้นยากพอ ๆ กัน (ไม่ใช่เพราะส่วนใหญ่ของลำดับไบต์นั้นไม่ถูกต้อง UTF-8 ในขณะที่การเข้ารหัสไลบรารีเหล่านี้พยายามแยกแยะอนุญาตให้ใช้ลำดับไบต์ที่เป็นไปได้ทั้งหมด) ดังนั้นไม่ใช่ทุกโปรแกรมที่ Unicode รู้จักทำการวิเคราะห์เช่นนั้นและพึ่งพา BOM แทน
โดยเฉพาะอย่างยิ่งคอมไพเลอร์และล่ามของ Microsoftและซอฟต์แวร์หลายชิ้นใน Microsoft Windows เช่น Notepad จะอ่านข้อความ UTF-8 ไม่ถูกต้องเว้นแต่จะมีเฉพาะอักขระ ASCII หรือเริ่มต้นด้วย BOM และจะเพิ่ม BOM เมื่อเริ่มต้นเมื่อบันทึก ข้อความเป็น UTF-8 Google เอกสารจะเพิ่ม BOM เมื่อมีการดาวน์โหลดเอกสาร Microsoft Word เป็นไฟล์ข้อความธรรมดา
สิ่งไหนดีกว่า มี หรือ ไม่มี BOM:
IETFแนะนำว่าหากโปรโตคอล (ก) มักจะใช้ UTF-8 หรือ (ข) มีบางส่วนทางอื่นที่จะระบุว่าการเข้ารหัสจะถูกนำมาใช้แล้วมัน“ควรห้ามการใช้ U + FEFF เป็นลายเซ็น.”
บทสรุปของฉัน:
ใช้ BOM ก็ต่อเมื่อความเข้ากันได้กับแอพพลิเคชั่นซอฟต์แวร์นั้นเป็นสิ่งจำเป็นอย่างยิ่ง
โปรดทราบว่าในขณะที่บทความ Wikipedia ที่อ้างถึงระบุว่าแอปพลิเคชันของ Microsoft จำนวนมากพึ่งพา BOM เพื่อตรวจจับ UTF-8 อย่างถูกต้อง แต่นี่ไม่ใช่กรณีสำหรับแอปพลิเคชัน Microsoft ทั้งหมด ยกตัวอย่างเช่นการชี้โดย@barlopเมื่อใช้งาน Windows Command Prompt กับ UTF-8 †คำสั่งดังกล่าวtype
และmore
ไม่ได้คาดหวัง BOM ที่จะนำเสนอ หากรายการวัสดุเป็นปัจจุบันก็อาจจะเป็นปัญหาที่มันเป็นสำหรับการใช้งานอื่น ๆ
† chcp
คำสั่งให้การสนับสนุน UTF-8 ( โดยไม่ต้อง BOM) ที่ผ่านหน้ารหัส65001
.htaccess
และgzip compression
เมื่อใช้ร่วมกับ UTF-8 BOM ให้ข้อผิดพลาดในการเข้ารหัสเปลี่ยนเป็นการเข้ารหัสใน UTF-8 โดยไม่ต้อง BOM ทำตามคำแนะนำตามที่อธิบายไว้ที่นี่เพื่อแก้ปัญหา
คำถามนี้มีคำตอบเป็นล้านคำตอบอยู่แล้วและหลายคำตอบก็ค่อนข้างดี แต่ฉันต้องการพยายามชี้แจงว่า BOM ควรหรือไม่ควรใช้
ดังที่ได้กล่าวมาการใช้ UTF BOM (Byte Order Mark) ใด ๆ ในการพิจารณาว่าสตริงนั้นเป็น UTF-8 หรือไม่นั้นจะได้รับการศึกษาการคาดเดา หากมีข้อมูลเมตาที่เหมาะสม (เช่นcharset="utf-8"
) แสดงว่าคุณรู้อยู่แล้วว่าคุณควรใช้อะไร แต่ไม่เช่นนั้นคุณจะต้องทดสอบและตั้งสมมติฐาน สิ่งนี้เกี่ยวข้องกับการตรวจสอบว่าไฟล์มาจากสตริงเริ่มต้นด้วยรหัสไบต์ฐานสิบหก EF BB BF หรือไม่
หากพบรหัสไบต์ที่สอดคล้องกับ UTF-8 BOM ความน่าจะเป็นสูงพอที่จะถือว่าเป็น UTF-8 และคุณสามารถไปจากที่นั่นได้ อย่างไรก็ตามเมื่อถูกบังคับให้ต้องเดาสิ่งนี้การตรวจสอบข้อผิดพลาดเพิ่มเติมในขณะที่อ่านยังคงเป็นความคิดที่ดีในกรณีที่มีบางอย่างที่อ่านไม่ออก คุณควรถือว่า BOM ไม่ใช่ UTF-8 (เช่น latin-1 หรือ ANSI) ถ้าอินพุตไม่ควรเป็น UTF-8 ตามแหล่งที่มา อย่างไรก็ตามถ้าไม่มี BOM คุณสามารถกำหนดได้ว่าควรจะเป็น UTF-8 หรือไม่โดยตรวจสอบการเข้ารหัส
หากคุณไม่สามารถบันทึกข้อมูลเมตาได้ด้วยวิธีอื่น (ผ่านแท็กชุดอักขระหรือเมตาดาต้าระบบไฟล์) และโปรแกรมที่ใช้เช่น BOM คุณควรเข้ารหัสด้วย BOM นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งใน Windows โดยทั่วไปแล้วสิ่งใดก็ตามที่ไม่มี BOM จะถือว่าใช้หน้ารหัสดั้งเดิม BOM บอกโปรแกรมเช่น Office ว่าใช่ข้อความในไฟล์นี้คือ Unicode นี่คือการเข้ารหัสที่ใช้
เมื่อพูดถึงมันไฟล์เดียวที่ฉันเคยมีปัญหาจริงๆคือไฟล์ CSV ขึ้นอยู่กับโปรแกรมว่าจะต้องมีหรือไม่มี BOM ตัวอย่างเช่นหากคุณใช้ Excel 2007+ บน Windows จะต้องเข้ารหัสด้วย BOM หากคุณต้องการเปิดอย่างราบรื่นและไม่ต้องหันไปใช้การนำเข้าข้อมูล
ควรสังเกตว่าสำหรับไฟล์บางไฟล์คุณต้องไม่มี BOM แม้กระทั่งบน Windows ตัวอย่างSQL*plus
หรือVBScript
ไฟล์ ในกรณีที่ไฟล์ดังกล่าวมี BOM คุณจะได้รับข้อผิดพลาดเมื่อพยายามเรียกใช้งาน
UTF-8 พร้อม BOM จะช่วยได้ก็ต่อเมื่อไฟล์มีอักขระที่ไม่ใช่ ASCII บางตัวเท่านั้น ถ้ามันรวมอยู่ด้วยและไม่มีเลยก็จะทำให้แอปพลิเคชั่นรุ่นเก่าที่อาจตีความไฟล์เป็น ASCII ธรรมดา แอปพลิเคชันเหล่านี้จะล้มเหลวอย่างแน่นอนเมื่อพวกเขาเจออักขระที่ไม่ใช่ ASCII ดังนั้นในความเห็นของฉัน BOM ควรถูกเพิ่มเมื่อไฟล์สามารถทำได้เท่านั้นและไม่ควรตีความว่าเป็น ASCII ธรรมดาอีกต่อไป
ฉันต้องการทำให้ชัดเจนว่าฉันไม่ต้องการมี BOM เลย เพิ่มเข้าไปในหากขยะเก่าบางชิ้นไม่มีอยู่และการแทนที่แอปพลิเคชันรุ่นเก่านั้นไม่สามารถทำได้
อย่าทำสิ่งใดคาดหวัง BOM สำหรับ UTF-8
อ้างถึงที่ด้านล่างของหน้า Wikipedia บน BOM: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
"ไม่จำเป็นต้องใช้ BOM หรือแนะนำสำหรับ UTF-8 แต่อาจพบในบริบทที่ข้อมูล UTF-8 ถูกแปลงจากรูปแบบการเข้ารหัสอื่น ๆ ที่ใช้ BOM หรือที่ BOM ใช้เป็นลายเซ็น UTF-8"
UTF-8 ที่ไม่มี BOM ไม่มี BOM ซึ่งไม่ได้ทำให้ดีไปกว่า UTF-8 ที่มี BOM ยกเว้นเมื่อผู้ใช้ไฟล์ต้องการทราบ (หรือจะได้ประโยชน์จากการรู้) ว่าไฟล์นั้นเข้ารหัส UTF-8 หรือไม่ หรือไม่.
BOM มักจะมีประโยชน์ในการกำหนด endianness ของการเข้ารหัสซึ่งไม่จำเป็นสำหรับกรณีการใช้งานส่วนใหญ่
นอกจากนี้ BOM อาจเป็นเสียง / ความเจ็บปวดที่ไม่จำเป็นสำหรับผู้บริโภคที่ไม่ทราบหรือไม่สนใจและอาจส่งผลให้เกิดความสับสนของผู้ใช้
ฉันมองสิ่งนี้จากมุมมองที่ต่างออกไป ฉันคิดว่าUTF-8 พร้อม BOM จะดีกว่าเพราะให้ข้อมูลเพิ่มเติมเกี่ยวกับไฟล์ ฉันใช้ UTF-8 ที่ไม่มี BOM ก็ต่อเมื่อฉันประสบปัญหา
ฉันกำลังใช้หลายภาษา (แม้กระทั่งCyrillic ) บนหน้าของฉันเป็นเวลานานและเมื่อไฟล์ถูกบันทึกโดยไม่มี BOM และฉันเปิดพวกเขาอีกครั้งเพื่อแก้ไขด้วยโปรแกรมแก้ไข (เป็นเทวดาระบุไว้ด้วย) อักขระบางตัวเสีย
โปรดทราบว่า Windows คลาสสิก ' Notepadจะบันทึกไฟล์ด้วย BOM โดยอัตโนมัติเมื่อคุณพยายามบันทึกไฟล์ที่สร้างขึ้นใหม่ด้วยการเข้ารหัส UTF-8
ฉันเป็นการส่วนตัวบันทึกไฟล์สคริปต์ฝั่งเซิร์ฟเวอร์(.asp, .ini, .aspx) ด้วย BOMและไฟล์ .html โดยไม่ต้อง BOM
chcp 65001
สำหรับการสนับสนุน utf8 ก็คือ utf8 โดยไม่มี bom ถ้าคุณทำtype myfile
มันจะแสดงอย่างถูกต้องหากไม่มีระเบิด หากคุณทำecho aaa>a.a
หรือecho אאא>a.a
ส่งออกตัวอักษรไปยังไฟล์ aa และคุณมี chcp 65001 มันจะส่งออกโดยไม่มี BOM
เมื่อคุณต้องการแสดงข้อมูลที่เข้ารหัสใน UTF-8 คุณอาจไม่ประสบปัญหา ประกาศตัวอย่างเช่นเอกสาร HTML เป็น UTF-8 และคุณจะมีทุกสิ่งที่แสดงในเบราว์เซอร์ของคุณที่อยู่ในเนื้อหาของเอกสาร
แต่นี่ไม่ใช่กรณีเมื่อเรามีข้อความเป็นCSVและ XML ทั้งบน Windows หรือ Linux
ตัวอย่างเช่นไฟล์ข้อความใน Windows หรือ Linux ซึ่งเป็นหนึ่งในสิ่งที่ง่ายที่สุดเท่าที่จะจินตนาการได้มันไม่ใช่ UTF-8 (ปกติ)
บันทึกเป็น XML และประกาศเป็น UTF-8:
<?xml version="1.0" encoding="UTF-8"?>
มันจะไม่แสดง (มันจะไม่สามารถอ่านได้) อย่างถูกต้องแม้ว่ามันจะประกาศเป็น UTF-8
ฉันมีชุดของข้อมูลที่ประกอบด้วยตัวอักษรภาษาฝรั่งเศสซึ่งจำเป็นต้องได้รับการบันทึกเป็น XML สำหรับการเผยแพร่ โดยไม่ต้องสร้างไฟล์ UTF-8 จากจุดเริ่มต้น (เปลี่ยนตัวเลือกใน IDE และ "สร้างไฟล์ใหม่") หรือเพิ่ม BOM ที่จุดเริ่มต้นของไฟล์
$file="\xEF\xBB\xBF".$string;
ฉันไม่สามารถบันทึกตัวอักษรภาษาฝรั่งเศสในไฟล์ XML ได้
ข้อแตกต่างที่เป็นประโยชน์อย่างหนึ่งคือถ้าคุณเขียนเชลล์สคริปต์สำหรับ Mac OS X และบันทึกเป็น UTF-8 ธรรมดาคุณจะได้รับการตอบกลับ:
#!/bin/bash: No such file or directory
เพื่อตอบสนองต่อสาย shebang ที่ระบุว่าคุณต้องการใช้เชลล์ใด:
#!/bin/bash
หากคุณบันทึกเป็น UTF-8 ไม่มี BOM (พูดเป็นBBEdit ) ทั้งหมดจะดี
ตามที่กล่าวไว้ข้างต้น UTF-8 ที่มี BOM อาจทำให้เกิดปัญหากับซอฟต์แวร์ที่ไม่ได้รับการยอมรับ BOM (หรือที่เข้ากันได้) ฉันเคยแก้ไขไฟล์ HTML ที่เข้ารหัสเป็น UTF-8 + BOM ด้วย Mozilla-based KompoZerเนื่องจากไคลเอนต์ต้องการโปรแกรมWYSIWYG
เลย์เอาต์จะถูกทำลายอย่างถาวรเมื่อบันทึก ฉันใช้เวลาสักระยะเพื่อทำความคุ้นเคยกับสิ่งนี้ ไฟล์เหล่านี้ทำงานได้ดีใน Firefox แต่พบว่ามีการเล่นโวหาร CSS ใน Internet Explorer ที่ทำลายเลย์เอาต์อีกครั้ง หลังจากเล่นซอกับไฟล์ CSS ที่ลิงก์นานหลายชั่วโมงแล้วก็ไม่มีประโยชน์ฉันค้นพบว่า Internet Explorer ไม่ชอบไฟล์ HTML BOMfed ไม่มีอีกครั้ง.
นอกจากนี้ฉันเพิ่งพบสิ่งนี้ใน Wikipedia:
อักขระ shebang จะแสดงด้วยสองไบต์เดียวกันในการเข้ารหัส ASCII แบบขยายรวมถึง UTF-8 ซึ่งโดยทั่วไปจะใช้สำหรับสคริปต์และไฟล์ข้อความอื่น ๆ ในระบบที่คล้าย Unix ในปัจจุบัน อย่างไรก็ตามไฟล์ UTF-8 อาจเริ่มต้นด้วยเครื่องหมายสั่งทางเลือก (BOM); หากฟังก์ชั่น "exec" ตรวจพบไบต์ 0x23 0x21 โดยเฉพาะการแสดงตนของ BOM (0xEF 0xBB 0xBF) ก่อนที่ shebang จะป้องกันไม่ให้ล่ามสคริปต์ทำงาน ผู้มีอำนาจบางคนแนะนำให้ต่อต้านการใช้เครื่องหมายคำสั่งไบต์ในสคริปต์ POSIX (เหมือน Unix), [15] ด้วยเหตุผลนี้และสำหรับการทำงานร่วมกันที่กว้างขึ้นและข้อกังวลทางปรัชญา
คำถามที่พบบ่อยเกี่ยวกับ Unicode Byte Order Mark (BOM)ให้คำตอบโดยย่อ:
ถาม: ฉันควรจัดการกับ BOM อย่างไร
ตอบ: ต่อไปนี้เป็นแนวทางปฏิบัติบางประการ:
โปรโตคอลเฉพาะ (เช่นข้อตกลงของ Microsoft สำหรับไฟล์. txt) อาจต้องใช้ BOM ในสตรีมข้อมูล Unicode บางไฟล์เช่นไฟล์ เมื่อคุณจำเป็นต้องปฏิบัติตามโปรโตคอลดังกล่าวให้ใช้ BOM
โปรโตคอลบางตัวอนุญาต BOM ที่เป็นตัวเลือกในกรณีของข้อความที่ไม่ได้ติดแท็ก ในกรณีเหล่านั้น
ในกรณีที่ทราบว่าสตรีมข้อมูลข้อความเป็นข้อความธรรมดา แต่จากการเข้ารหัสที่ไม่รู้จัก BOM สามารถใช้เป็นลายเซ็นได้ หากไม่มี BOM การเข้ารหัสอาจเป็นอะไรก็ได้
ตำแหน่งที่สตรีมข้อมูลข้อความเป็นที่รู้จักกันว่าเป็นข้อความ Unicode ธรรมดา (แต่ไม่ใช่ endian ใด ๆ ) ดังนั้น BOM จึงสามารถใช้เป็นลายเซ็นได้ หากไม่มี BOM ข้อความควรถูกตีความเป็น big-endian
โปรโตคอลแบบไบต์บางตัวคาดหวังอักขระ ASCII ที่จุดเริ่มต้นของไฟล์ หากใช้ UTF-8 กับโปรโตคอลเหล่านี้ควรหลีกเลี่ยงการใช้ BOM เนื่องจากการเข้ารหัสลายเซ็นฟอร์ม
ในกรณีที่ทราบชนิดของสตรีมข้อมูลที่แม่นยำ (เช่น Unicode big-endian หรือ Unicode little-endian) ไม่ควรใช้ BOM โดยเฉพาะอย่างยิ่งทุกครั้งที่มีการประกาศสตรีมข้อมูลเป็น UTF-16BE, UTF-16LE, UTF-32BE หรือ UTF-32LE BOM จะต้องไม่ใช้ BOM
จากhttp://en.wikipedia.org/wiki/Byte-order_mark :
เครื่องหมายคำสั่งไบต์ (BOM) เป็นอักขระ Unicode ที่ใช้เพื่อส่งสัญญาณ endianness (ลำดับไบต์) ของไฟล์ข้อความหรือสตรีม จุดรหัสคือ U + FEFF การใช้ BOM เป็นทางเลือกและหากใช้ควรปรากฏที่จุดเริ่มต้นของสตรีมข้อความ นอกเหนือจากการใช้งานที่เฉพาะเจาะจงเป็นตัวบ่งชี้ลำดับไบต์อักขระ BOM อาจระบุว่ามีการเข้ารหัส Unicode หลายข้อความที่เข้ารหัส
การใช้ BOM ในไฟล์ของคุณเสมอจะทำให้แน่ใจได้ว่ามันเปิดอย่างถูกต้องในตัวแก้ไขที่รองรับ UTF-8 และ BOM
ปัญหาที่แท้จริงของฉันกับการขาด BOM มีดังต่อไปนี้ สมมติว่าเรามีไฟล์ซึ่งประกอบด้วย:
abc
หากไม่มี BOM จะเป็นการเปิดเป็น ANSI ในโปรแกรมแก้ไขส่วนใหญ่ ดังนั้นผู้ใช้รายอื่นของไฟล์นี้จึงเปิดไฟล์และผนวกอักขระดั้งเดิมบางตัวเช่น
abg-αβγ
อุ๊ปส์ ... ตอนนี้ไฟล์ยังอยู่ใน ANSI และคาดเดาว่า "αβγ" ไม่มีขนาด 6 ไบต์ แต่ 3 นี่ไม่ใช่ UTF-8 และทำให้เกิดปัญหาอื่น ๆ ในภายหลังในสายการพัฒนา
นี่คือประสบการณ์ของฉันกับ Visual Studio, Sourcetreeและคำขอดึงซึ่งทำให้ฉันมีปัญหาบางอย่าง:
ดังนั้นจึงกลายเป็น BOM ที่มีลายเซ็นต์จะมีตัวอักษรจุดสีแดงในแต่ละไฟล์เมื่อตรวจสอบคำขอดึง (มันอาจจะค่อนข้างน่ารำคาญ)
หากคุณวางไว้บนมันก็จะแสดงตัวละครเช่น "ufeff" แต่ปรากฎว่า Sourcetree ไม่แสดง bytemarks ประเภทเหล่านี้ดังนั้นมันจะจบลงด้วยการดึงคำขอของคุณซึ่งน่าจะเป็นเพราะ Visual Studio 2017 เข้ารหัสไฟล์ใหม่ตอนนี้ดังนั้นบางที Bitbucket ควรเพิกเฉยต่อสิ่งนี้หรือทำให้มันแสดงในอีกทางหนึ่งข้อมูลเพิ่มเติมที่นี่:
UTF ที่มี BOM จะดีกว่าถ้าคุณใช้ UTF-8 ในไฟล์ HTML และถ้าคุณใช้ Serbian Cyrillic, Serbian Latin, German, Hungarian หรือภาษาแปลก ๆ ในหน้าเดียวกัน
นั่นคือความคิดเห็นของฉัน (30 ปีของการใช้คอมพิวเตอร์และอุตสาหกรรมไอที)