Có gì khác nhau giữa UTF-8 và UTF-8 mà không có BOM ? Cái nào tốt hơn?
Có gì khác nhau giữa UTF-8 và UTF-8 mà không có BOM ? Cái nào tốt hơn?
Câu trả lời:
BOM UTF-8 là một chuỗi các byte khi bắt đầu một luồng văn bản ( 0xEF, 0xBB, 0xBF
) cho phép người đọc đoán một cách đáng tin cậy hơn một tệp được mã hóa trong UTF-8.
Thông thường, BOM được sử dụng để báo hiệu endianness của một mã hóa, nhưng vì endianness là không thích hợp sang UTF-8, BOM là không cần thiết.
Theo tiêu chuẩn Unicode , BOM cho các tệp UTF-8 không được khuyến nghị :
2.6 Sơ đồ mã hóa
... Việc sử dụng BOM không bắt buộc và cũng không được khuyến nghị cho UTF-8, nhưng có thể gặp phải trong các bối cảnh nơi dữ liệu UTF-8 được chuyển đổi từ các hình thức mã hóa khác sử dụng BOM hoặc sử dụng BOM làm chữ ký UTF-8 . Xem phần phụ của Đơn hàng Byte của Mark Byt trong Phần 16.8, Đặc biệt , để biết thêm thông tin.
Các câu trả lời xuất sắc khác đã trả lời rằng:
EF BB BF
Nhưng, như thông tin bổ sung cho điều này, BOM cho UTF-8 có thể là một cách tốt để "ngửi" nếu một chuỗi được mã hóa trong UTF-8 ... Hoặc nó có thể là một chuỗi hợp pháp trong bất kỳ mã hóa nào khác ...
Ví dụ: dữ liệu [EF BB BF 41 42 43] có thể là:
Vì vậy, mặc dù có thể rất tuyệt khi nhận ra mã hóa nội dung tệp bằng cách xem các byte đầu tiên, bạn không nên dựa vào điều này, như hiển thị trong ví dụ trên
Mã hóa nên được biết, không được thần thánh.
Có ít nhất ba vấn đề với việc đưa BOM vào các tệp được mã hóa UTF-8.
Và, như những người khác đã đề cập, không có đủ và cũng không cần thiết phải có BOM để phát hiện ra rằng thứ gì đó là UTF-8:
cat
sẽ không mang lại cho bạn một kết quả rõ ràng , một kết quả chỉ có BOM khi bắt đầu. Nếu bạn có ý đó, thì đó là bởi vì cat
hoạt động ở cấp độ byte, không phải ở cấp độ nội dung được giải thích và theo cách tương tự cat
không thể đối phó với các bức ảnh, nói. Tuy nhiên, nó không gây hại nhiều. Đó là bởi vì BOM mã hóa một không gian không phá vỡ có chiều rộng bằng không.
Dưới đây là những ví dụ về việc sử dụng BOM thực sự gây ra vấn đề thực sự và nhiều người không biết về nó.
Các tập lệnh Shell, tập lệnh Perl, tập lệnh Python, tập lệnh Ruby, tập lệnh Node.js hoặc bất kỳ tập lệnh thực thi nào khác cần được chạy bởi một trình thông dịch - tất cả đều bắt đầu bằng một dòng shebang trông giống như một trong số đó:
#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node
Nó cho hệ thống biết trình thông dịch nào cần được chạy khi gọi tập lệnh như vậy. Nếu tập lệnh được mã hóa bằng UTF-8, người ta có thể muốn đưa BOM vào đầu. Nhưng thực ra là "#!" nhân vật không chỉ là nhân vật. Thực tế chúng là một con số ma thuật được tạo thành từ hai nhân vật ASCII. Nếu bạn đặt một cái gì đó (như BOM) trước các ký tự đó, thì tệp sẽ trông giống như nó có một số ma thuật khác và điều đó có thể dẫn đến các vấn đề.
Xem Wikipedia, bài viết: Shebang, phần: Số ma thuật :
Các ký tự shebang được biểu thị bằng hai byte giống nhau trong các bảng mã ASCII mở rộng, bao gồm UTF-8, thường được sử dụng cho các tập lệnh và các tệp văn bản khác trên các hệ thống giống như Unix hiện tại. Tuy nhiên, các tệp UTF-8 có thể bắt đầu bằng dấu thứ tự byte tùy chọn (BOM); nếu hàm "exec" đặc biệt phát hiện các byte 0x23 và 0x21, thì sự hiện diện của BOM (0xEF 0xBB 0xBF) trước khi shebang sẽ ngăn trình thông dịch kịch bản lệnh được thực thi.Một số nhà chức trách khuyên không nên sử dụng dấu thứ tự byte trong các tập lệnh POSIX (giống Unix), vì lý do này và vì khả năng tương tác rộng hơn và các mối quan tâm triết học. Ngoài ra, một dấu thứ tự byte là không cần thiết trong UTF-8, vì mã hóa đó không có vấn đề về tuổi thọ; nó chỉ phục vụ để xác định mã hóa là UTF-8. [nhấn mạnh thêm]
Xem RFC 7159, Phần 8.1 :
Việc triển khai KHÔNG PHẢI thêm dấu thứ tự byte vào đầu văn bản JSON.
Không chỉ là bất hợp pháp trong JSON, nó cũng không cần thiết để xác định mã hóa ký tự bởi vì có nhiều cách đáng tin cậy hơn để xác định rõ ràng cả mã hóa ký tự và độ bền được sử dụng trong bất kỳ luồng JSON nào (xem câu trả lời này để biết chi tiết).
Không chỉ bất hợp pháp trong JSON và không cần thiết , nó thực sự phá vỡ tất cả các phần mềm xác định mã hóa bằng phương thức được trình bày trong RFC 4627 :
Xác định mã hóa và độ bền của JSON, kiểm tra bốn byte đầu tiên cho byte 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
Bây giờ, nếu tệp bắt đầu bằng BOM, nó sẽ trông như thế này:
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
Lưu ý rằng:
Tùy thuộc vào việc triển khai, tất cả những thứ đó có thể được hiểu không chính xác là UTF-8 và sau đó bị hiểu sai hoặc bị từ chối là UTF-8 không hợp lệ hoặc hoàn toàn không được công nhận.
Ngoài ra, nếu việc triển khai kiểm tra JSON hợp lệ như tôi khuyến nghị, nó sẽ từ chối ngay cả đầu vào thực sự được mã hóa dưới dạng UTF-8, bởi vì nó không bắt đầu bằng ký tự ASCII <128 như RFC.
BOM trong JSON là không cần thiết, là bất hợp pháp và phá vỡ phần mềm hoạt động chính xác theo RFC. Nên là không có giới hạn khi không sử dụng nó sau đó, luôn có những người khăng khăng phá vỡ JSON bằng cách sử dụng BOM, nhận xét, quy tắc trích dẫn khác nhau hoặc các loại dữ liệu khác nhau. Tất nhiên bất cứ ai cũng có thể tự do sử dụng những thứ như BOM hoặc bất cứ thứ gì khác nếu bạn cần - chỉ cần đừng gọi nó là JSON.
Đối với các định dạng dữ liệu khác ngoài JSON, hãy xem nó thực sự trông như thế nào. Nếu mã hóa duy nhất là UTF- * và ký tự đầu tiên phải là ký tự ASCII thấp hơn 128 thì bạn đã có tất cả thông tin cần thiết để xác định cả mã hóa và độ bền của dữ liệu của bạn. Thêm các BOM ngay cả khi là một tính năng tùy chọn sẽ chỉ khiến nó phức tạp hơn và dễ bị lỗi hơn.
Đối với việc sử dụng bên ngoài JSON hoặc script, tôi nghĩ rằng đã có câu trả lời rất tốt ở đây. Tôi muốn thêm thông tin chi tiết cụ thể về kịch bản và tuần tự hóa, bởi vì đó là một ví dụ về các ký tự BOM gây ra vấn đề thực sự.
Có gì khác nhau giữa UTF-8 và UTF-8 không có BOM?
Câu trả lời ngắn: Trong UTF-8, BOM được mã hóa dưới dạng byte EF BB BF
ở đầu tệp.
Câu trả lời dài:
Ban đầu, người ta hy vọng rằng Unicode sẽ được mã hóa theo UTF-16 / UCS-2. BOM được thiết kế cho hình thức mã hóa này. Khi bạn có các đơn vị mã 2 byte, cần phải chỉ ra hai byte đó theo thứ tự nào và một quy ước chung để thực hiện điều này là bao gồm ký tự U + FEFF làm "Dấu thứ tự byte" ở đầu dữ liệu. Ký tự U + FFFE không được gán vĩnh viễn để có thể sử dụng sự hiện diện của nó để phát hiện thứ tự byte sai.
UTF-8 có cùng thứ tự byte bất kể tuổi thọ của nền tảng, do đó, không cần một dấu thứ tự byte. Tuy nhiên, nó có thể xảy ra (dưới dạng chuỗi byte EF BB FF
) trong dữ liệu đã được chuyển đổi thành UTF-8 từ UTF-16 hoặc dưới dạng "chữ ký" để chỉ ra rằng dữ liệu là UTF-8.
Cái nào tốt hơn?
Không có. Như Martin Côte đã trả lời, tiêu chuẩn Unicode không khuyến nghị điều đó. Nó gây ra vấn đề với phần mềm không nhận biết BOM.
Cách tốt hơn để phát hiện xem một tệp có phải là UTF-8 hay không là thực hiện kiểm tra tính hợp lệ. UTF-8 có các quy tắc nghiêm ngặt về chuỗi byte nào là hợp lệ, do đó xác suất dương tính giả là không đáng kể. Nếu một chuỗi byte trông giống như UTF-8, thì có lẽ là như vậy.
sh
, perl
, g++
, và nhiều công cụ miễn phí và mạnh mẽ khác. Bạn muốn mọi thứ để làm việc? Chỉ cần mua các phiên bản MS. MS đã tạo ra vấn đề dành riêng cho nền tảng, giống như thảm họa trong phạm vi \ x80- \ x95 của họ.
UTF-8 với BOM được xác định tốt hơn. Tôi đã đi đến kết luận này một cách khó khăn. Tôi đang làm việc trên một dự án trong đó một trong các kết quả là tệp CSV , bao gồm các ký tự Unicode.
Nếu tệp CSV được lưu mà không có BOM, Excel sẽ nghĩ đó là ANSI và hiển thị vô nghĩa. Khi bạn thêm "EF BB BF" ở phía trước (ví dụ: bằng cách lưu lại bằng Notepad với UTF-8; hoặc Notepad ++ với UTF-8 với BOM), Excel sẽ mở nó tốt.
Việc chuẩn bị ký tự BOM cho các tệp văn bản Unicode được RFC 3629 khuyến nghị: "UTF-8, định dạng chuyển đổi của ISO 10646", tháng 11 năm 2003 tại http://tools.ietf.org/html/rfc3629 (thông tin cuối cùng này được tìm thấy tại: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html )
BOM có xu hướng bùng nổ (không có ý định chơi chữ (sic)) ở đâu đó, một nơi nào đó. Và khi nó bùng nổ (ví dụ: không được trình duyệt, trình chỉnh sửa, v.v.) nhận ra, nó sẽ hiển thị dưới dạng các ký tự lạ 
ở đầu tài liệu (ví dụ: tệp HTML, phản hồi JSON , RSS , v.v.) và gây ra sự bối rối như vấn đề mã hóa gần đây gặp phải trong cuộc nói chuyện của Obama trên Twitter .
Thật khó chịu khi nó xuất hiện ở những nơi khó gỡ lỗi hoặc khi thử nghiệm bị bỏ qua. Vì vậy, tốt nhất là tránh nó trừ khi bạn phải sử dụng nó.
Câu hỏi: Có gì khác nhau giữa UTF-8 và UTF-8 mà không có BOM? Cái nào tốt hơn?
Dưới đây là một số trích đoạn từ bài viết Wikipedia về dấu thứ tự byte (BOM) mà tôi tin rằng cung cấp một câu trả lời chắc chắn cho câu hỏi này.
Về ý nghĩa của BOM và UTF-8:
Tiêu chuẩn Unicode cho phép BOM trong UTF-8 , nhưng không yêu cầu hoặc không khuyến nghị sử dụng. Thứ tự byte không có ý nghĩa trong UTF-8, do đó, việc sử dụng duy nhất trong UTF-8 là để báo hiệu khi bắt đầu luồng văn bản được mã hóa trong UTF-8.
Đối số KHÔNG sử dụng BOM:
Động lực chính cho việc không sử dụng BOM là khả năng tương thích ngược với phần mềm không nhận biết Unicode ... Một động lực khác để không sử dụng BOM là khuyến khích UTF-8 làm mã hóa "mặc định".
Lập luận CHO sử dụng một BOM:
Đối số cho việc sử dụng BOM là không có nó, cần phải phân tích heuristic để xác định ký tự nào mã hóa một tệp đang sử dụng. Trong lịch sử phân tích như vậy, để phân biệt các mã hóa 8 bit khác nhau, rất phức tạp, dễ bị lỗi và đôi khi chậm. Một số thư viện có sẵn để giảm bớt tác vụ, chẳng hạn như Trình phát hiện bộ ký tự phổ quát Mozilla và Các thành phần quốc tế cho Unicode.
Các lập trình viên lầm tưởng rằng việc phát hiện UTF-8 cũng khó khăn không kém (không phải vì phần lớn các chuỗi byte là UTF-8 không hợp lệ, trong khi các mã hóa mà các thư viện này đang cố gắng phân biệt cho phép tất cả các chuỗi byte có thể). Do đó, không phải tất cả các chương trình nhận biết Unicode đều thực hiện phân tích như vậy và thay vào đó dựa vào BOM.
Cụ thể, trình biên dịch và trình thông dịch của Microsoft và nhiều phần mềm trên Microsoft Windows như Notepad sẽ không đọc chính xác văn bản UTF-8 trừ khi nó chỉ có các ký tự ASCII hoặc bắt đầu bằng BOM và sẽ thêm BOM vào đầu khi lưu văn bản dưới dạng UTF-8. Google Docs sẽ thêm BOM khi tài liệu Microsoft Word được tải xuống dưới dạng tệp văn bản thuần túy.
Trên đó là tốt hơn, VỚI hoặc KHÔNG CÓ BOM:
Các IETF khuyến cáo rằng nếu một giao thức (a) luôn luôn sử dụng UTF-8, hoặc (b) có một số cách khác để chỉ những gì mã hóa đang được sử dụng, sau đó nó “NÊN cấm sử dụng U + FEFF như một chữ ký.”
Kết luận của tôi:
Sử dụng BOM chỉ nếu khả năng tương thích với một ứng dụng phần mềm là hoàn toàn cần thiết.
Cũng lưu ý rằng mặc dù bài viết Wikipedia được tham chiếu chỉ ra rằng nhiều ứng dụng của Microsoft dựa vào BOM để phát hiện chính xác UTF-8, nhưng đây không phải là trường hợp của tất cả các ứng dụng của Microsoft. Ví dụ, như ra nhọn bởi @barlop , khi sử dụng Command Windows Prompt với UTF-8 † , lệnh như vậy type
và more
tôi không mong đợi các BOM có mặt. Nếu BOM có mặt, nó có thể có vấn đề như đối với các ứng dụng khác.
† Các chcp
lệnh Mời hỗ trợ cho UTF-8 ( mà không cần sự BOM) thông qua mã trang 65001 .
.htaccess
và gzip compression
kết hợp với BOM UTF-8 gây ra lỗi mã hóa Thay đổi thành Mã hóa trong UTF-8 mà không có BOM làm theo đề xuất như được giải thích ở đây giải quyết các vấn đề
Câu hỏi này đã có một câu trả lời một triệu và nhiều câu trả lời khá hay, nhưng tôi muốn thử và làm rõ khi nào BOM nên hay không nên sử dụng.
Như đã đề cập, bất kỳ việc sử dụng BOM UTF (Dấu thứ tự Byte) trong việc xác định xem một chuỗi có phải là UTF-8 hay không là phỏng đoán có giáo dục. Nếu có sẵn siêu dữ liệu thích hợp (như charset="utf-8"
), thì bạn đã biết những gì bạn sẽ sử dụng, nhưng nếu không, bạn sẽ cần phải kiểm tra và đưa ra một số giả định. Điều này liên quan đến việc kiểm tra xem tệp có xuất phát từ chuỗi bắt đầu bằng mã byte thập lục phân hay không, EF BB BF.
Nếu tìm thấy mã byte tương ứng với BOM UTF-8, xác suất đủ cao để giả sử đó là UTF-8 và bạn có thể đi từ đó. Tuy nhiên, khi buộc phải đưa ra dự đoán này, kiểm tra lỗi bổ sung trong khi đọc vẫn sẽ là một ý tưởng tốt trong trường hợp có thứ gì đó bị cắt xén. Bạn chỉ nên giả sử BOM không phải là UTF-8 (tức là latin-1 hoặc ANSI) nếu đầu vào chắc chắn không nên là UTF-8 dựa trên nguồn của nó. Tuy nhiên, nếu không có BOM, bạn chỉ cần xác định liệu nó có phải là UTF-8 hay không bằng cách xác nhận mã hóa.
Nếu bạn không thể ghi siêu dữ liệu theo bất kỳ cách nào khác (thông qua thẻ ký tự hoặc meta hệ thống tệp) và các chương trình đang được sử dụng như BOM, bạn nên mã hóa bằng BOM. Điều này đặc biệt đúng trên Windows khi mọi thứ không có BOM thường được cho là đang sử dụng trang mã kế thừa. BOM nói với các chương trình như Office rằng, vâng, văn bản trong tệp này là Unicode; đây là mã hóa được sử dụng.
Khi nói đến nó, các tệp duy nhất tôi thực sự gặp vấn đề là CSV. Tùy thuộc vào chương trình, nó phải hoặc không phải có BOM. Ví dụ: nếu bạn đang sử dụng Excel 2007+ trên Windows, nó phải được mã hóa bằng BOM nếu bạn muốn mở nó một cách trơn tru và không phải dùng đến việc nhập dữ liệu.
Cần lưu ý rằng đối với một số tệp, bạn không được có BOM ngay cả trên Windows. Ví dụ là SQL*plus
hoặc VBScript
tập tin. Trong trường hợp các tệp như vậy chứa BOM, bạn sẽ gặp lỗi khi bạn cố thực thi chúng.
UTF-8 với BOM chỉ giúp nếu tệp thực sự chứa một số ký tự không phải ASCII. Nếu nó được bao gồm và không có bất kỳ thứ gì, thì nó có thể sẽ phá vỡ các ứng dụng cũ hơn có thể giải thích tệp là ASCII đơn giản. Các ứng dụng này chắc chắn sẽ thất bại khi chúng gặp một ký tự không phải ASCII, vì vậy theo tôi, BOM chỉ nên được thêm vào khi tệp có thể, và không nên được hiểu là ASCII đơn giản.
Tôi muốn làm rõ rằng tôi không muốn có BOM nào cả. Thêm nó vào nếu một số rác cũ bị hỏng mà không có nó, và thay thế ứng dụng cũ đó là không khả thi.
Đừng làm bất cứ điều gì mong đợi BOM cho UTF-8.
Được trích dẫn ở cuối trang Wikipedia trên BOM: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
"Việc sử dụng BOM không bắt buộc và cũng không được khuyến nghị cho UTF-8, nhưng có thể gặp phải trong các bối cảnh nơi dữ liệu UTF-8 được chuyển đổi từ các hình thức mã hóa khác sử dụng BOM hoặc trong đó BOM được sử dụng làm chữ ký UTF-8"
UTF-8 không có BOM không có BOM, điều này không làm cho nó tốt hơn UTF-8 với BOM, ngoại trừ khi người tiêu dùng tệp cần biết (hoặc sẽ có lợi khi biết) liệu tệp có được mã hóa UTF-8 không hay không.
BOM thường hữu ích để xác định độ bền của mã hóa, không cần thiết cho hầu hết các trường hợp sử dụng.
Ngoài ra, BOM có thể là tiếng ồn / nỗi đau không cần thiết cho những người tiêu dùng không biết hoặc không quan tâm đến nó và có thể dẫn đến sự nhầm lẫn của người dùng.
Tôi nhìn điều này từ một quan điểm khác. Tôi nghĩ UTF-8 với BOM tốt hơn vì nó cung cấp thêm thông tin về tệp. Tôi chỉ sử dụng UTF-8 mà không có BOM nếu tôi gặp vấn đề.
Tôi đang sử dụng nhiều ngôn ngữ (thậm chí Cyrillic ) trên các trang của mình trong một thời gian dài và khi các tệp được lưu mà không có BOM và tôi mở lại chúng để chỉnh sửa bằng trình chỉnh sửa (như cherouvim cũng lưu ý), một số ký tự bị hỏng.
Lưu ý rằng Notepad cổ điển của Windows sẽ tự động lưu tệp bằng BOM khi bạn cố lưu tệp mới được tạo bằng mã hóa UTF-8.
Cá nhân tôi lưu các tệp kịch bản phía máy chủ (.asp, .ini, .aspx) bằng các tệp BOM và .html mà không có BOM .
chcp 65001
để hỗ trợ utf8, đó là utf8 không có bom. Nếu bạn làm điều type myfile
đó sẽ chỉ hiển thị đúng nếu không có bom. Nếu bạn làm echo aaa>a.a
hoặc echo אאא>a.a
xuất ký tự ra tệp aa và bạn có chcp 65001, nó sẽ xuất ra mà không có BOM.
Khi bạn muốn hiển thị thông tin được mã hóa trong UTF-8, bạn có thể không gặp phải vấn đề gì. Khai báo ví dụ một tài liệu HTML là UTF-8 và bạn sẽ có mọi thứ được hiển thị trong trình duyệt của bạn được chứa trong phần thân của tài liệu.
Nhưng đây không phải là trường hợp khi chúng ta có tệp văn bản, CSV và XML, trên Windows hoặc Linux.
Ví dụ: một tệp văn bản trong Windows hoặc Linux, một trong những thứ dễ nhất có thể tưởng tượng, nó không phải (thường là) UTF-8.
Lưu nó dưới dạng XML và khai báo nó dưới dạng UTF-8:
<?xml version="1.0" encoding="UTF-8"?>
Nó sẽ không hiển thị (nó sẽ không được đọc) một cách chính xác, ngay cả khi nó được khai báo là UTF-8.
Tôi đã có một chuỗi dữ liệu chứa các chữ cái tiếng Pháp, cần được lưu dưới dạng XML để cung cấp. Không tạo tệp UTF-8 ngay từ đầu (thay đổi tùy chọn trong IDE và "Tạo tệp mới") hoặc thêm BOM ở đầu tệp
$file="\xEF\xBB\xBF".$string;
Tôi đã không thể lưu các chữ cái tiếng Pháp trong một tệp XML.
Một sự khác biệt thực tế là nếu bạn viết một tập lệnh shell cho Mac OS X và lưu nó dưới dạng UTF-8 đơn giản, bạn sẽ nhận được phản hồi:
#!/bin/bash: No such file or directory
để đáp ứng với dòng shebang chỉ định shell nào bạn muốn sử dụng:
#!/bin/bash
Nếu bạn lưu dưới dạng UTF-8, không có BOM (nói trong BBEdit ) tất cả sẽ ổn.
Như đã đề cập ở trên, UTF-8 với BOM có thể gây ra sự cố với phần mềm không nhận biết BOM (hoặc tương thích). Tôi đã từng chỉnh sửa các tệp HTML được mã hóa dưới dạng UTF-8 + BOM với KompoZer dựa trên Mozilla , vì khách hàng yêu cầu chương trình WYSIWYG .
Luôn luôn bố trí sẽ bị phá hủy khi tiết kiệm. Tôi phải mất một thời gian để tìm hiểu về cách này. Các tệp này sau đó hoạt động tốt trong Firefox, nhưng lại cho thấy một sự giải quyết CSS trong Internet Explorer phá hủy bố cục. Sau khi loay hoay với các tệp CSS được liên kết trong nhiều giờ mà không có kết quả, tôi phát hiện ra rằng Internet Explorer không thích tệp HTML BOMfed. Không bao giờ lặp lại.
Ngoài ra, tôi chỉ tìm thấy điều này trong Wikipedia:
Các ký tự shebang được biểu thị bằng hai byte giống nhau trong các bảng mã ASCII mở rộng, bao gồm UTF-8, thường được sử dụng cho các tập lệnh và các tệp văn bản khác trên các hệ thống giống như Unix hiện tại. Tuy nhiên, các tệp UTF-8 có thể bắt đầu bằng dấu thứ tự byte tùy chọn (BOM); nếu hàm "exec" đặc biệt phát hiện các byte 0x23 0x21, thì sự hiện diện của BOM (0xEF 0xBB 0xBF) trước khi shebang sẽ ngăn trình thông dịch kịch bản lệnh được thực thi. Một số nhà chức trách khuyên không nên sử dụng dấu thứ tự byte trong các tập lệnh POSIX (giống như Unix), vì lý do này và vì khả năng tương tác rộng hơn và mối quan tâm triết học
Câu hỏi thường gặp về Dấu hiệu đặt hàng Unicode (BOM) cung cấp câu trả lời ngắn gọn:
Q: Làm thế nào tôi nên đối phó với BOM?
A: Dưới đây là một số hướng dẫn để làm theo:
Một giao thức cụ thể (ví dụ: các quy ước của Microsoft cho các tệp .txt) có thể yêu cầu sử dụng BOM trên các luồng dữ liệu Unicode nhất định, chẳng hạn như các tệp. Khi bạn cần tuân thủ một giao thức như vậy, hãy sử dụng BOM.
Một số giao thức cho phép các BOM tùy chọn trong trường hợp văn bản không được mã hóa. Trong những trường hợp đó,
Trong đó một luồng dữ liệu văn bản được biết là văn bản thuần túy, nhưng mã hóa không xác định, BOM có thể được sử dụng làm chữ ký. Nếu không có BOM, mã hóa có thể là bất cứ thứ gì.
Trong đó một luồng dữ liệu văn bản được biết là văn bản Unicode đơn giản (nhưng không phải là endian), thì BOM có thể được sử dụng làm chữ ký. Nếu không có BOM, văn bản nên được hiểu là big endian.
Một số giao thức hướng byte mong đợi các ký tự ASCII ở đầu tệp. Nếu UTF-8 được sử dụng với các giao thức này, nên sử dụng BOM làm chữ ký biểu mẫu mã hóa.
Trong đó loại chính xác của luồng dữ liệu được biết đến (ví dụ: Unicode big endian hoặc Unicode little endian), không nên sử dụng BOM. Đặc biệt, bất cứ khi nào một luồng dữ liệu được khai báo là UTF-16BE, UTF-16LE, UTF-32BE hoặc UTF-32LE thì không được sử dụng BOM.
Từ http://en.wikipedia.org/wiki/Byte-order_mark :
Dấu thứ tự byte (BOM) là một ký tự Unicode được sử dụng để báo hiệu độ bền (thứ tự byte) của tệp văn bản hoặc luồng. Điểm mã của nó là U + FEFF. Việc sử dụng BOM là tùy chọn và, nếu được sử dụng, sẽ xuất hiện ở đầu luồng văn bản. Ngoài việc sử dụng cụ thể của nó như là một chỉ báo theo thứ tự byte, ký tự BOM cũng có thể chỉ ra biểu thức Unicode nào trong số các biểu diễn Unicode mà văn bản được mã hóa.
Luôn sử dụng BOM trong tệp của bạn sẽ đảm bảo rằng nó luôn mở chính xác trong trình chỉnh sửa hỗ trợ UTF-8 và BOM.
Vấn đề thực sự của tôi với sự vắng mặt của BOM là như sau. Giả sử chúng ta có một tệp chứa:
abc
Không có BOM, điều này sẽ mở ra như ANSI trong hầu hết các trình soạn thảo. Vì vậy, một người dùng khác của tệp này mở nó và thêm một số ký tự gốc, ví dụ:
abg-αβγ
Rất tiếc ... Bây giờ tệp vẫn ở ANSI và đoán xem, "αβγ" không chiếm 6 byte, nhưng 3. Đây không phải là UTF-8 và điều này gây ra các vấn đề khác sau này trong chuỗi phát triển.
Dưới đây là kinh nghiệm của tôi với các yêu cầu kéo Visual Studio, Sourcetree và Bitbucket, điều này đã gây ra cho tôi một số vấn đề:
Vì vậy, hóa ra BOM có chữ ký sẽ bao gồm một ký tự chấm đỏ trên mỗi tệp khi xem xét yêu cầu kéo (nó có thể khá khó chịu).
Nếu bạn di chuột lên nó, nó sẽ hiển thị một ký tự như "ufeff", nhưng hóa ra Sourcetree không hiển thị các loại phụ đề này, vì vậy rất có thể nó sẽ kết thúc trong các yêu cầu kéo của bạn, điều đó sẽ ổn vì đó là Visual Studio 2017 mã hóa các tệp mới ngay bây giờ, vì vậy có lẽ Bitbucket nên bỏ qua điều này hoặc làm cho nó hiển thị theo cách khác, thông tin thêm ở đây:
UTF với BOM sẽ tốt hơn nếu bạn sử dụng UTF-8 trong các tệp HTML và nếu bạn sử dụng tiếng Serbia Cyrillic, tiếng Serbia Latin, tiếng Đức, tiếng Hungary hoặc một số ngôn ngữ kỳ lạ trên cùng một trang.
Đó là ý kiến của tôi (30 năm trong ngành điện toán và CNTT).