Or you want a quick look: Utf-8 là gì? Tại sao chúng ta cần hiểu về utf-8?
Utf-8 là gì là một trong những keyword được search nhiều nhất trên Google về chủ đề utf-8 là gì. Trong bài viết này, vuidulich.vn sẽ viết bài viết Utf-8 là gì? Tại sao chúng ta cần hiểu về utf-8?
Utf-8 là gì? Tại sao chúng ta cần hiểu về utf-8?
Chúng ta thường nghe nhiều đến Unicode, UTF-8, UTF16, hay Shift-JS.
Trong bài này chỉ xin sử dụng rõ những định nghĩa này để khi gặp phải vấn đề về Charset hay Encoding mà có phương án thích hợp.
- Bảng mã kí tự là gìA?
- Encoding là gì?
- Unicode, Shift-JIS, UTF8, UTF16 nói lên điều gì?
1. Bảng mã kí tự là gì?
Bảng mã kí tự (char code table) là một bảng dùng để đánh chỉ số cho một tâp kí tự (char) ,sao cho mỗi kí tự được ánh xạ từ số duy nhất (code). trị giá của code luôn được đánh số liên tiếp gia tăng. Điều này tạo sẽ tạo thứ tự cho từng kí tự trong tập kí tự ở trên.
Ta đang biết đến bảng mã ASCII:
Ở bảng trên, ta thấy cột Char, giới thiệu kí tự; Các cột Dec(hay Hex) chứa giá trị ánh xạ đến kí tự tương ứng ở cột Char.
Rất dễ để hiểu định nghĩa bảng mã, những cái gây khó khăn là ở phần 2
2. Encoding là gì?
Ta vừa mới có khái niệm về bảng mã kí tự. Đến đây thôi, về cơ bản, nó chẳng không giống nào cái thực đơn bảng giá ở quán. Giờ ta mong muốn dùng các kí tự của cái bảng đó trong máy tính tính, ta cần một cách thức để mapping các kí tự đó vào máy tính.
diễn tả thế nào đây? Có một phương thức rất hay được sử dụng trong trường hợp này : Đó là mọi kí tự được lưu trữ trên bộ nhớ với cùng độ dài byte.
Nếu trị giá từ 0 ~ 100 : ta cần 1 byte ( vì giá trị có thể sẽ là khoảng: 0 ~ 255) Nếu trị giá từ 0 ~ 60000 : ta cần 2 byte (vì trị giá đủ sức sẽ là khoảng: 0 ~ 65535) Nếu trị giá từ 0 ~ 1000 : ta vẫn cần 2 byte (vì giá trị đủ sức sẽ là khoảng: 0 ~ 1000)d
Với công thức này, giá trị được lưu xuống chính là giá trị trong bảng mã kí tự ở trên, nên các gía trị được lưu xuống đuơng nhiên giống với gía trị ghi trong bảng.
Ví dụ: như bảng ASCII chẳng hạn, ta cần 1 byte : A -> 65 (0x41); B -> 66 (0x42) Giả sử encoding một tập con của Unicode (từ 0x0000 -> 0xFFFF) theo hướng dẫn này, ta sẽ cần 2 byte. À -> 0x00C0 -> sẽ luôn luôn đuợc lưu là 0x00C0. A -> 0x00C1 -> sẽ luôn luôn được lưu xuống là 0x00C1. Nếu cứ sử dụng với cách này mọi bảng mã đều đuợc Encode ngon lành.
Nhưng có 1 chủ đề ở đây, giả sử mọi người đều sử dụng Unicode (giá trị to nhất hiện nay là 0x1F8FF), tức là cần khoảng 3 byte để encode all. Nếu vậy, những tài liệu mà chỉ sử dụng ASCII sẽ có kích thước gấp 3 bình thường. Cái này hoàn toàn không ổn. Vậy làm sao???? Một lý do nữa liên quan đến lịch sử. Đó là trước khi máy tính được phổ biến mọi nơi, thì nó gần như chỉ được sử ở Mỹ. Và bảng mã được dùng phổ biến ở hầu hết các máy tính là ASCII, và bí quyết mã hóa với độ dài cố định 1 byte. Giờ xuất hiện thêm rất nhiều kí tự, người đọc sẽ giúp gi? Việc dùng bảng mã mới là đương nhiên, nhưng phương pháp mã hóa sẽ như thế nào? Liệu họ có bỏ phương thức độ dài cố định 1 byte để thay thế bằng cố định nhiều byte???
3. Unicode, Shift-JS, UTF8, UTF16
Unicode là bảng mã chứa gần như toàn bộ các kí tự của hầu hết các ngôn ngữ trên toàn cầu. Shift-JIS là bảng mã được dùng ở gần như tất cả các máy tính tại Nhật, được JIS đưa ra. UTF8 là cái gì? Là cách thức Encoding rất đa dạng để diễn đạt bảng mã Unicode trên bộ nhớ. Khi người ta luận bàn để đưa ra bí quyết Encoding bảng mã Unicode này trên máy tính. dĩ nhiên họ toàn là người Mỹ, họ mong muốn cả thế giới đủ sức dùng Unicode, nhưng không muốn bỏ mẹo Encoding cũ của họ cho ASCII. Họ mang ra phương pháp sau:
Với các kí tự từ 0(0x00) ~ 127(0x7F) (tức là của ASCII - có 128 kí tự) : vẫn là 1 byte. : 0X*0vvvvvvv Với các kí tự từ **0x80 ~ 0x7FF* (có 1920 kí tự) sẽ dùng 2 byte : 0x*110vvvvv 0x10vvvvvv Với các kí tự từ **0x800 ~ 0xFFFF* (có 63488 kí tự) sẽ sử dụng 3 byte : 0x*1110vvvv 0x10vvvvvv 0x10*vvvvvv …
Một vài gợi ý nhận đuợc từ hướng dẫn Encoding trên ASCII luôn luôn là ASCII, luôn luôn là 1 byte Kí tự A -> 65 -> 0x41; B -> 66 -> 0x42 Kí tự ngoài ASCII sẽ giống như thế nào: Á -> 0x00C0, mã binary 1100 0000, gía trị của mã này nằm ở khoảng 0x80 -> 0x7FF nên trị giá ghi xuống phải ở dạng 0x*110vvvvv 0x10vvvvvv Sẽ encode như sau: Ta tách 6 bit cuối của kí tự đặt vào 6 bit cuối của byte thấp, hay byte thấp sẽ có gía trị là : 0x10000000 Còn 2 bit 11 của kí tự, ta đặt vào 2 bit cuối của byte cao, hay byte cao sẽ có giá trị là : 0x110vvv11, các bit k đuợc đặt cho bằng 0 hết, nên byte cao sẽ có giá trị là: 0x11000011 Cuối cùng ta được giá trị Encode của Á trong bằng UTF-8 là *0xC380**. (Đúng theo liên kết giáo khoa vuidulich.vn/en/00C0/)
Cứ giống như vậy để mapping đến hết bảng unicode. Ta thấy rằng, với mẹo encode này, trị giá trong bảng và giá trị đuợc lưu trữ không phải luôn luôn giống nhau nữa (trừ ASCII). Ta sẽ thấy số các bit được đánh dấu đậm ở trên có trị giá cố định sẽ sử dụng để nhận biết. lệ thuộc các đuợc bit cố định ở đầu mỗi byte này mà chương trình đọc (editor,…) sẽ biết được đó là kí tự 1 byte (ASCII) hay kí tự nhiều byte.
Với các encode trên, các tài liệu viết bằng ASCII đương nhiên có dung lượng tối ưu. Các kí tự châu Á hầu hết sẽ đuợc biểu diễn ở dạng 2 byte. Điều này dẫn tới những khẳng định rằng “UTF8 là 2 byte, hay Unicode là 2 byte.”. Tiếng Việt có dấu của chúng ta 2 byte ảnh giống như là đúng, còn toàn bộ thì không phải. (Theo comment bạn @LeHuy11 bên dưới)
Dù có rất nhiều ưu thế như trên. Nó luôn luôn nhược điểm. Đó là các kí tự của một số nước mà nằm ngoài khoảng 0x80 ->0x7FF sẽ phải biểu diễn bằng 3 byte. kéo đến cái đĩa cài Window cho Thái có dung lượng gấp 3 cái đĩa cài cho US???(Cái này đoán mò) Và microsoft không dùng UTF-8 như là Encoding mặc định của họ. Dường giống như họ sử dụng UTF16. ( Mong người xung quanh confirm giúp)
UTF16 Gần giống với hướng dẫn Encode của UTF-8 nhưng nó sử dụng luôn 2 byte để encode cho cả ASCII.
ví dụ A -> 65 -> 0x41 -> sẽ đuợc Encode thành 0x0041; B -> 66 -> 0x42 -> sẽ được Encode thành 0x0042.
Á -> 0x00C0 -> sẽ đuợc Encode thành 0x00C0. À -> 0x00C1 -> sẽ đuợc Encode thành 0x00C1. (Đúng theo link giáo khoa vuidulich.vn/en/00C0/)
Với phương pháp trên các kí tự ASCII sẽ có số byte gấp đôi. tuy nhiên dải kí tự từ 0x0000 -> 0xFFFF sẽ chỉ sử dụng 2 byte mà thôi. Với khoảng này, nó phủ gần như như all kí tự của thế giới rồi. Đĩa cài Window ở nơi nào cũng giống như ở đâu, click thước giống nhau. :))
nguồn: vuidulich.vn