algolia search

Tìm thấy x bài viết trong xms.

Có gì khác nhau giữa UTF-8 và UTF-8 without BOM

Có gì khác nhau giữa UTF-8 và UTF-8 without BOM


What's different between UTF-8 and UTF-8 without BOM?

Chắc hẳn các bạn cũng đã ít nhất một lần nghe qua cụm “UTF-8 without BOM” rồi phải không? Vậy thì có thể bạn cũng (đã) thắc mắc sự khác biệt giữa 2 thứ đấy cũng như BOM là gì. Và liệu UTF-8 BOM (còn gọi là UTF-8) hay UTF-8 without BOM tốt hơn 🤔🤔🤔

BOM là gì? UTF-8 BOM

Theo “Unicode Standard“, BOM là viết tắt của “Byte Order Mark“. Mời các bạn xem hình dưới đây

BOM là gì?

Để dễ hình dung, UTF-8 BOM sẽ luôn có 3 bytes EF BB BF ở đầu một file (bạn phải xem ở dạng Hex mới rõ) để xác định / đánh dấu rằng file đó có được lưu ở dạng UTF-8 hay không. Đọc đến đây thì có thể bạn sẽ thắc mắc là vậy thì nó có thực sự cần thiết? Vì cơ bản là file đó đã có dạng UTF-8 rồi còn gì?

Sự khác biệt hay chẳng có gì cả!

Về cơ bản, thực ra không có sự khác biệt chính thức giữa UTF­-8 và UTF­-8 BOM (mập mờ ý), bởi vì về nguyên tắc, 3 bytes EF BB BF sẽ được loại bỏ khi đọc nội dung (string) từ file / stream. Nhưng phải nói thêm, BOM của UTF-8 là một cách rất hay để biết được liệu nội dung đó có được mã hóa (encode) ở dạng UTF-8 hay không, hay nó đơn thuần chỉ là một dạng mã hóa khác. Mà vấn đề là hay thôi thì chưa đủ.

Có rất nhiều loại mã để mã hóa hay định dạng chữ viết của từng khu vực / quốc gia khác nhau, bạn có thể thấy như của Việt Nam là Windows-1258, Châu Âu có nhiều loại như ISO 8859­1, Windows-1252..

Để dễ hình dung, ta có nội dung sau của một file text thuần. [EF BB BF 41 42 43]

Vậy nếu file được đọc dưới dạng ISO­8859­1 thì sẽ có nội dung là “ï»¿ABC“, còn đọc ở dạng UTF-8 thì chỉ có nội dung là “ABC” (đã bỏ đi 3 bytes đầu tiên).

Vậy nên bạn có thể dùng 3 bytes đầu tiên của một file để xem xem file đó được lưu dựa trên chuẩn mã hóa nào, có phải là UTF-8 hay không.

Vấn đề của BOM

Ngoài thực tế dễ thấy là bạn có thể dễ dàng xem loại định dạng của files, thì ta cũng có 3 vấn đề dễ gặp phải của một file được mã hóa bằng UTF-8 BOM.

  1. Những file chẳng chứa gì cả (theo nghĩa đen, chỉ có cái xác file rỗng thôi) sẽ không thực sự “chẳng chứa gì” bởi vì luôn luôn có 3 bytes BOM nằm trong file đó. (Hack não vl chưa nè 😅😅)
    Tóm tắt: File UTF-8 BOM không bao giờ là file rỗng
  2. Những file chỉ chứa dữ liệu là ASCII mà thôi (các bạn đi thi hoặc xử lý dữ liệu đọc từ file phải chú ý) thì không còn là ASCII toàn bộ nữa, bởi vì bộ 3 bytes BOM bản thân nó không phải là ASCII. Điều này có thể làm hỏng toàn bộ bài làm hoặc công cụ đọc nội dung, và rất khó để thay thế  chúng với các công cụ thường gặp. Khi bạn mở lên, hiển nhiên công cụ đọc sẽ tự động loại bỏ 3 bytes BOM đi, nhưng nó vẫn nằm ở đó, và sẽ luôn có trong bộ nhớ khi bạn đọc nó, chỉ là bạn không thấy thôi. Và thế là bạn chết.
    Tóm tắt: 3 bytes đầu tiên của BOM sẽ giết bạn như một con nhái khi đi thi 😄😄
  3. Những trường hợp chia nhỏ file sẽ gặp trục trặc vì 3 bytes BOM luôn cản trở / chắn đường khi bạn nối / ghép nội dung của những file này lại với nhau. 😤😤

BOM có cần thiết không nhỉ?

Theo mình tìm hiểu, phần lớn các nhận định không đánh giá cao BOM và coi nó như đồ thừa khi chỉ dùng nó để xác định rằng nội dung có ở dạng UTF-8 hay không. Giống như khi xét kỹ thì nó không có điều kiện cần (necessary) và đủ (sufficient) để hoàn thành công việc mà đáng ra nó phải nhận.

Điều kiện cần: Thực tế bạn chỉ cần đọc xem liệu các bytes đó có phải UTF-8 hay không (đơn giản là nó khác với ASCII); nếu bạn đọc được, thì tức là nội dung hoàn toàn có thể xem là UTF-8. Nó không cần.

Điều kiện đủ: Một vài trường hợp ngẫu nhiên chắc chắn có thể xảy ra là bạn mã hóa bit nhưng khi lưu xuống lại bị trùng với bộ 3 bytes BOM, nên khi đọc lại 3 bytes này biến mất và thế là hỏng dữ liệu. Tức là nếu chỉ dựa vào 3 bytes để xác định thì sẽ luôn có trường hợp ngoại lệ làm nó ‘sai’ đi. Nó không hữu dụng trong tất cả trường hợp.

Theo Unicode standard thì BOM không được khuyến khích sử dụng, vì nếu ứng dụng là một phiên bản không hỗ trợ việc đọc BOM thì ứng dụng đó hoàn toàn không thể sử dụng được với các nội dung chứa BOM.

Có một cách hay để phát hiện xem một nội dung (string) có ở dạng UTF-8 hay không là hãy thực hiện một bài kiểm tra tính hợp lệ của nội dung đó. UTF-8 có những quy định nghiêm ngặt về giá trị của các chuỗi byte trong nội dung, vì vậy xác suất của một nội dung bị sai lệch (không phải là UTF-8 nhưng bị hiểu là UTF-8) là không đáng kể. Nếu một chuỗi byte tương tự như quy định của UTF-8, thì nó chắc (chắn) là UTF-8.

Vậy là xong rồi, hẹn gặp các bạn ở bài khác 🙂

Nội dung lượm lặt từ Stackoverflow.

Chung Nguyễn Blog dẫn lại từ Jack Reive Blog

Đánh giá bài viết

Thích thì like
Có gì khác nhau giữa UTF-8 và UTF-8 without BOM
5/5 1 votes

Bình luận

Hiển thị bình luận Facebook