Tìm hiểu Unicode

Is Unicode a 16-bit encoding?

Ví dụ câu trả lời bạn chọn là Đúng, xin chúc mừng, bạn đã sai, đừng buồn vì ít ra bạn đã có 1 đồng chí là mình =))

1 điều mà nhiều người tới nay vẫn nhầm tưởng là Unicode dùng 16 bit để mã hóa, bởi vậy nó chỉ có thể mã hóa cao nhất} 65536 ký tự động. Điều này hoàn toàn ko chính xác.

Thực ra, phiên bản trước tiên của Unicode đúng là dùng 16 bit để mã hóa, từ 5 1991 tới 1995. Nhưng từ lúc Unicode 2.0 ra đời (06/1996), nó ko còn dùng chỉ 16 bit để mã hóa nữa. Chuẩn Unicode mã hóa ký tự động trong dải từ U+0000 tới U+10FFFF, tức là bao gồm ko gian mã khoảng 21 bit. Tùy thuộc} vào phương thức mã hóa được dùng (UTF-8, UTF-16, UTF-32), từng ký tự động sẽ được biểu diễn bởi 1 chuỗi từ 1-4 đơn vị mã 8 bit (tương đương 1-4 byte), từ 1-2 đơn vị mã 16 bit, hoặc chỉ 1 đơn vị mã 32 bit duy nhất.

Trước lúc Unicode ra đời, thế giới đã tồn tại hàng trăm hệ mã hóa, tuy nhiên lại chưa có bất kỳ hệ nào lưu trữ được toàn bộ mọi ký tự động. Nổi bật nhất chắc hẳn có lẽ là ASCII, bảng mã dựa trên chữ loại Latin được dùng trong tiếng Anh tiên tiến.

Chính xác thì ASCII dùng 7 bit biểu diễn sở hữu 7 số nhị phân (thập phân từ 0 tới 127). Từ 32 tới 127 là những ký tự động in được, tức là hiển thị được, dí dụ ‘ ‘ là 32, chữ loại ‘A’ là 65. Mã dưới 32 được dùng để biểu diễn ký tự động điều khiển (management character), dí dụ như nút ESC, Backspace.

Rõ ràng chỉ sở hữu 7, thậm chi là 8 bit, bạn chỉ biểu diễn được cao nhất} 256 ký tự động, từng đấy quá đủ sở hữu tiếng Anh, nhưng sở hữu ngôn ngữ khác thì ko thể. Vậy những hệ mã hóa khác thì sao? Những hệ mã hóa này lại xung đột sở hữu nhau. Thí dụ cả 2 đều cùng dùng 1 số để biểu diễn 2 ký tự động khác biệt, hoặc lại dùng 2 số khác nhau để biểu diễn cùng 1 ký tự động. Từng 1 máy tính đều tương trợ nhiều chuẩn mã hóa, chính vì vậy mà từng lúc dữ liệu được trao đổi giữa những chuẩn mã hóa thì nguy cơ sai lệch luôn tồn tại.

Unicode ra đời để giải quyết vấn đề này. Nó phân phối 1 biểu diễn số duy nhất cho từng 1 ký tự động, mà ko cần lưu ý tới ứng dụng, chương trình hay ngôn ngữ là gì. Chuẩn Unicode (Unicode Customary) phân phối 1 phương thức nhất quán để mã hóa toàn bộ ngôn ngữ viết trên thế giới. Để mã ký tự động trông đơn giản và hiệu quả, nó sẽ gán 1 ký tự động sở hữu 1 số duy nhất. Chuẩn Unicode tương trợ 3 hình thức mã hóa như mình đã nói trên trên, bao gồm UTF-8, UTF-16 và UTF-32, mã hóa cùng 1 bộ ký tự động, dĩ nhiên.

Bảng mã Unicode

Vậy thì Unicode thực sự là gì? Unicode là 1 bảng mã, nó ánh xạ 1 số duy nhất tới 1 ký tự động (ký tự động này có thể là chữ loại tiếng Anh như “a”, “b” hoặc tiếng Việt “á”, “ớ”, tiếng Nhật hoặc là những ký tự động đặc biệt như “$”, “%”, dấu chấm câu “.”, “,”…)

Từng số như vậy được gọi là 1 điểm mã (code level), 1 khái niệm mang trong mình tính lý thuyết. Còn việc điểm mã được biểu diễn trong bộ nhớ hay ổ đĩa là 1 câu chuyện hoàn toàn khác. Từng điểm mã được biểu diễn dưới dạng U+0639. “U+” tượng trưng cho “Unicode”, còn phần hệ số là hệ hexa. Thí dụ, điểm mã U+0041 là số hexa 0041 (tương đương số thập phân 65). Nó biểu diễn ký tự động “A” trong chuẩn Unicode.

Xem Thêm  Sau A Là Gì – Ngữ Pháp Tiếng Anh: Mạo Từ A – Có Nghĩa Là Gì, Ý Nghĩa La Gi 2023

Từng ký tự động được gán 1 tên duy nhất để phân biệt nó sở hữu ký tự động khác. Chẳng hạn, U+0041 được gán tên là “LATIN CAPITAL LETTER A”. U+0A1B được gán sở hữu tên “GURMUKHI LETTER CHA”.

Lấy dí dụ 1 xâu ký tự động:

Hiya

trong Unicode, xâu ký tự động này tương ứng sở hữu 5 điểm mã (lưu ý là 5 điểm mã chứ ko cần 5 byte)

U+0048 U+0065 U+006C U+006C U+006F

Số chữ loại mà Unicode có thể định nghĩa là ko giới hạn, trên thực tế nó vượt xa con số 65536. phiên bản Unicode new nhất là 9.0.0, biểu diễn tổng số 128172 ký tự động.

1 số thuật ngữ thường dùng trong Unicode như: ko gian mã (code house), airplane, code unit, block…

Ko gian mã là ko gian chứa đa số những điểm mã của Unicode. 1 thuật ngữ khác là airplane. Unicode chia thành 17 airplane, từng airplane chứa 65,536 ký tự động (tương đương 16 bit), bởi vậy tổng kích thước ko gian mã của Unicode là 17 × 65,536 = 1,114,112. Hiện tại sở hữu phiên bản Unicode 9.0 mình đã đề cập trên trên thì chỉ dùng chưa tới 10% ko gian mã. 1 điều cần nói thêm là Unicode sẽ hạn chế chỉ sở hữu 17 airplane, tức là sẽ ko xảy ra việc cần tới airplane thứ 18 để biểu diễn ký tự động, ko gian mã sở hữu hơn 1 triệu ký tự động có thể được mã hóa đã quá đủ cho phần tiêu của Unicode, chính vì vậy mà chuẩn Unicode ko có ý định mở rộng thêm ko gian mã tới airplane thứ 18 hoặc hơn.

Để hiểu hơn về airplane, mọi người có thể xem lại định dạng điểm mã Unicode U+0639. Như lúc đầu mình đã nói thì chuẩn Unicode mã hóa ký tự động trong dải từ U+0000 tới U+10FFFF. Từng airplane sẽ dùng 65536 ký tự động, tương đương từ 0000 – FFFF trong hệ hexa. 17 airplane, tức tương đương đánh số thứ tự động từ 0 tới 16 trong hệ thập phân, tức là 00-10 trong hệ hexa, 2 số này sẽ chiếm 2 vùng trước tiên trong định dạng 6 số (hhhhhh).

Chung quy lại định dạng điểm mã Unicode có dạng U+000639, sở hữu “U+” là Unicode, 2 số đầu để mô tả airplane, 4 số cuối là điểm mã trong airplane đấy. Airplane trước tiên gọi là Fundamental Multilingual Airplane, đây là airplane quan yếu nhất (airplane 0), chứa sắp như gần như hệ thống chữ viết và ký hiệu thường dùng trên thế giới. Chứa ký tự động thuộc khoảng U+0000 tới U+FFFF.

Đơn vị mã (code unit), thuật ngữ này lại liên quan tới phương thức mã hóa. Chẳng hạn sở hữu UTF-8 thì code unit là 1 byte, UTF-16 thì code unit là 2 byte, trong lúc UTF-32 là 4 byte.

Blocks: chỉ đơn giản là 1 dải những điểm mã mà có 1 đặc điểm chung nào đấy, về mặt ngôn ngữ hoặc chức năng. Chẳng hạn block trước tiên, từ U+0000 tới U+001F là dải mã để biểu diễn những ký tự động điều khiển (management character), gồm 32 ký tự động. Block tiếp theo tên là Fundamental Latin, khởi đầu từ U+0020 tới U+007F, đây cũng chính là dải mã biểu diễn những ký tự động trong bảng mã ASCII…

Xem Thêm  Wipe Out là gì và cấu trúc cụm từ Wipe Out trong câu Tiếng Anh

Tiếng Việt của mình thì dùng những ký tự động trong block Fundamental Latin, để biểu diễn những ký tự động ko dấu, như “a”, “A”. Còn những ký tự động có dấu như “á”, “ấ”, “Ớ” thì thuộc block Latin-1 Complement, Latin Prolonged-B và Latin Prolonged Further. Thông tin về những Unicode block khách hàng có thể tra cứu trên đây.

Những phương thức mã hóa Unicode (Encoding)

Phương thức dịch điểm mã sang nhị phân được gọi là mã hóa ký tự động (character encoding). Như đã nói, Unicode có 3 phương thức mã hóa: UTF-8, UTF-16 và UTF-32

UTF-32: đây là phương thức mã hóa Unicode đơn giản nhất. Từng điểm mã được biểu diễn quản lý bằng 1 đơn vị mã 32 bit

UTF-16: trong kiểu mã hóa này, từng điểm mã trong airplane 0 (U+0000 tới U+FFFF) được biểu diễn bằng 1 đơn vị mã 16 bit, những điểm mã từ airplane 1 trở đi cần dùng 1 cặp đơn vị mã 16 bit để biểu diễn.

UTF-8: tương tự động như UTF-32 và UTF-16, kiểu mã hóa này dùng đơn vị mã 8 bit, và nó có thể biểu diễn được mọi ký tự động trong dải U+0000 tới U+10FFFF, điểm khác biệt duy nhất sở hữu 2 kiểu mã hóa trên là UTF-8 tương thích sở hữu ASCII.

Trong bài viết này mình sẽ trình bày kỹ về UTF-8, phương thức mã hóa được dùng phổ thông} nhất hiện nay. Hiểu được bí quyết UTF-8 mã hóa sẽ giúp chúng ta có loại nhìn toàn diện hơn về việc mã hóa ký tự động. 1 số ưu điểm của nó:

  1. UTF-8 có thể biểu diễn được mọi điểm mã Unicode
  2. Nó tương thích của ASCII
  3. Nó tiết kiệm ko gian hơn so sở hữu những kiểu mã hóa anh em của nó như UTF-16 hay UTF-32. Ký tự động mã hóa theo kiểu UTF-8 có thể thuộc khoảng từ 1-4 byte. Sở hữu văn bản tiếng Anh thông thường thì chỉ cần dùng 1-2 byte để biểu diễn 1 ký tự động.
  4. UTF-8 ko bắc buộc dùng BOM (byte order mark)

Để thực sự hiểu bí quyết UTF-8 encoding làm cho việc, chúng ta có thể xem bảng sau, tóm tắt về phương thức mã hóa như sau:

  1. Sở hữu ký tự động chỉ có 1 byte (gần như là ASCII), bit trước tiên sẽ luôn là 0 để tương thích sở hữu ASCII
  2. Sở hữu ký tự động multi-byte, byte trước tiên sẽ khởi đầu sở hữu từ 2-4 số 1 để biểu diễn số byte ký tự động sẽ dùng, theo sau là 1 số 0
  3. Phần bit còn lại trong byte trước tiên và những byte tiếp theo được dùng để điền những bit biểu diễn điểm mã, ngoại trừ việc từng byte tiếp theo sẽ khởi đầu sở hữu 10

Từ dí dụ U+00A3 chúng ta lấy giá trị thập phân của A3 là 163 và chuyển sang hệ nhị phân, đấy là 10100011. Chú ý rằng cần 8 số nhị phân để biểu diễn số này trong hệ nhị phân. Trong lúc đấy giả dụ là single-byte thì luôn cần khởi đầu bằng 0 để tương thích sở hữu ASCII, thế nên để biểu diễn ký tự động có điểm mã là U+00A3 chúng ta cần 2 byte.

Vì là ký từ multi-byte nên byte trước tiên sẽ khởi đầu bằng 2 số 1 để chỉ ra rằng có 2 byte cần được dùng, theo sau là 1 số 0, tiếp tới là những bit của điểm mã chúng ta cần điền. Lúc này byte trước tiên sẽ có dạng là 110xxxxx

Xem Thêm  ” Tiêu Binh Là Gì ? Nghĩa Của Từ Tiêu Binh Trong Tiếng Nga Neu Confessions

Thêm vào đấy trên phần 3 mình có đề cập là những byte sau byte trước tiên luôn được khởi đầu sở hữu 10. Vì vậy sở hữu 3 bit trước tiên của byte thứ 1 là 110, 2 bit trước tiên của byte thứ 2 là 10, chúng ta đã dùng 5 bit để dùng cho định dạng kiểu mã hóa, lúc này chỉ còn lại 11 bit để lấp đầy bằng điểm mã. Vì giá trị nhị phân của U+00A3 là 10100011, chỉ có 8 bit, ta mặc định thêm 3 số 0 vào đầu nữa cho đủ 11 bit, thành 00010100011, từ giá trị này chúng ta chỉ việc lấp vào số bit còn thừa đã tính trên trên, cắt từ trái sang cần. Như vậy byte trước tiên sẽ là

11000010

byte tiếp theo sẽ là

10100011

Ví dụ vẫn còn mập mờ thì bạn có thể xem thêm dí dụ minh họa trên đây, vô cùng dễ hiểu.

Ứng dụng

Vậy là thời gian này} chắc hẳn khách hàng cũng đã hiểu được phần nào về Unicode và kiểu mã hóa UTF-8 rồi. Hãy thử trả lời mấy câu hỏi sau xem sao nhé (à trên editor nhớ lưu lại sở hữu encoding là UTF-8 nhé) =))

$str_jp = ‘た’; $str_vn_1 = ‘á’; $str_vn_2 = ‘ớ’; 1. strlen($str_jp) 2. mb_strlen($str_jp, ‘UTF-8’); 3. $str_jp[0]; 4. $str_jp[0] . $str_jp[1] . $str_jp[2]; 5. strlen($str_vn_1); 6. strlen($str_vn_2);

Đáp án sẽ là

1. 3 2. 1 3. � 4. わ 5. 2 6. 3

Câu thứ 1 và thứ 2 thì đơn giản rồi, strlen đo chiều dài xâu ký tự động dựa trên số byte, còn mb_strlen đo chiều dài dựa trên encoding, bộ ký tự động tiếng Nhật mã hóa theo UTF-8 thì cần dùng 3 byte, nên strlen trả về 3, còn mb_strlen trả về 1.

Vì kiểu $str[index] sẽ trả về byte tại vùng index, nên đương nhiên kết quả sẽ lỗi, vì trình thông qua cũng như bộ giải mã ko hiểu đây là loại gì, bởi giả dụ chuyển sang hệ nhị phân thì nó là 11100011, ko trùng sở hữu bất cứ ký tự động nào (facepalm)

Trên câu 4, đơn giản chỉ là nối 3 byte lại sở hữu nhau, Unicode sẽ dựa vào byte trước tiên, cũng chính là 11100011, nó sẽ biết rằng đây là byte định dạng cho ký tự động, 3 số 1 chứng tỏ ký tự động này cần 3 byte để biểu diễn, thế nên nó chỉ việc tìm thêm 2 byte tiếp theo là sẽ biết được đấy là ký tự động gì. Vì định dạng của 2 byte sau đều là 10xxxxxx, bạn có thể thử tráo vị trị 2 byte này, sẽ ra được 1 ký tự động khác mà ko hề xảy ra lỗi, theo dí dụ trên thì giả dụ

$str_jp[0] . $str_jp[2] . $str_jp[1]

sẽ cho output là

ký tự động này có điểm mà Unicode là U+33C2 (có vẻ ko liên quan nhiều) =))

Câu thứ 5 và thứ 6, có lẽ bạn cảm thấy khá lạ, vì cùng là ký tự động tiếng Việt mà lại có độ dài byte khác nhau, nguyên nhân là vì tiếng Việt mình dùng ký tự động thuộc nhiều block khác nhau, có trên cả Fundamental Latin (vốn là ASCII, nên chỉ có 1 byte), rồi Latin-1 Complement, Latin Prolonged-B và Latin Prolonged Further, nên nó có thể có độ dài từ 1 tới 3 byte, và kết quả strlen cũng thay thế đổi tùy thuộc} theo ký tự động đấy dùng bao nhiêu byte.

Vậy là xong, mong rằng qua bài viết này thì bạn cũng có loại nhìn rõ hơn về Unicode và xử lý ký tự động bất nhắc là single-byte hay multi-byte. Thanks for studying!

Tài liệu tham khảo:

  1. http://unicode.org
  2. http://www.joelonsoftware.com/articles/Unicode.html
  3. https://en.wikipedia.org/wiki/UTF-8