Bạn không thể phụ thuộc vào việc tệp có BOM. UTF-8 không yêu cầu nó. Và các bảng mã không phải Unicode thậm chí không có BOM. Tuy nhiên, có những cách khác để phát hiện mã hóa.
UTF-32
BOM là 00 00 FE FF (cho BE) hoặc FF FE 00 00 (cho LE).
Nhưng UTF-32 rất dễ phát hiện ngay cả khi không có BOM. Điều này là do phạm vi điểm mã Unicode bị hạn chế ở U + 10FFFF và do đó, các đơn vị UTF-32 luôn có dạng 00 {00-10} xx xx (cho BE) hoặc xx xx {00-10} 00 (cho LE) . Nếu dữ liệu có độ dài là bội số của 4 và tuân theo một trong các mẫu này, bạn có thể yên tâm cho rằng đó là UTF-32. Kết quả dương tính giả gần như không thể xảy ra do sự hiếm hoi của 00 byte trong các mã hóa hướng byte.
US-ASCII
Không có BOM, nhưng bạn không cần một. ASCII có thể dễ dàng được xác định bằng cách thiếu byte trong phạm vi 80-FF.
UTF-8
BOM là EF BB BF. Nhưng bạn không thể dựa vào điều này. Rất nhiều tệp UTF-8 không có BOM, đặc biệt nếu chúng có nguồn gốc trên hệ thống không phải Windows.
Nhưng bạn có thể an toàn giả định rằng nếu một tệp xác thực là UTF-8, thì nó là UTF-8. Dương tính giả rất hiếm.
Cụ thể, do dữ liệu không phải là ASCII, tỷ lệ dương tính giả đối với chuỗi 2 byte chỉ là 3,9% (1920/49152). Đối với một chuỗi 7 byte, nó nhỏ hơn 1%. Đối với chuỗi 12 byte, nó nhỏ hơn 0,1%. Đối với một chuỗi 24 byte, nó nhỏ hơn 1 trên một triệu.
UTF-16
BOM là FE FF (cho BE) hoặc FF FE (cho LE). Lưu ý rằng UTF-16LE BOM được tìm thấy ở đầu UTF-32LE BOM, vì vậy hãy kiểm tra UTF-32 trước.
Nếu bạn tình cờ có một tệp chủ yếu bao gồm các ký tự ISO-8859-1, thì việc có một nửa số byte của tệp là 00 cũng sẽ là một chỉ báo mạnh về UTF-16.
Mặt khác, cách đáng tin cậy duy nhất để nhận ra UTF-16 mà không có BOM là tìm các cặp thay thế (D [8-B] xx D [CF] xx), nhưng các ký tự không phải BMP quá hiếm khi được sử dụng để làm cho phương pháp này trở nên thực tế .
XML
Nếu tệp của bạn bắt đầu bằng các byte 3C 3F 78 6D 6C (tức là các ký tự ASCII "<? Xml"), thì hãy tìm một encoding=
khai báo. Nếu có, hãy sử dụng bảng mã đó. Nếu không có, thì giả sử UTF-8, là kiểu mã hóa XML mặc định.
Nếu bạn cần hỗ trợ EBCDIC, hãy tìm chuỗi tương đương 4C 6F A7 94 93.
Nói chung, nếu bạn có định dạng tệp chứa khai báo mã hóa, thì hãy tìm khai báo đó thay vì cố gắng đoán mã hóa.
Không có cái nào ở trên
Có hàng trăm bảng mã khác, đòi hỏi nhiều nỗ lực hơn để phát hiện. Tôi khuyên bạn nên thử trình dò mã ký tự của Mozilla hoặc cổng .NET của nó .
Một mặc định hợp lý
Nếu bạn đã loại trừ các mã hóa UTF và không có khai báo mã hóa hoặc phát hiện thống kê chỉ ra một mã hóa khác, hãy giả sử ISO-8859-1 hoặc Windows-1252 có liên quan chặt chẽ . (Lưu ý rằng tiêu chuẩn HTML mới nhất yêu cầu khai báo “ISO-8859-1” được hiểu là Windows-1252.) Là trang mã mặc định của Windows cho tiếng Anh (và các ngôn ngữ phổ biến khác như tiếng Tây Ban Nha, tiếng Bồ Đào Nha, tiếng Đức và tiếng Pháp), đó là kiểu mã hóa thường gặp nhất ngoài UTF-8.