Tìm hiểu Unicode

Chúng tôi rất vui mừng chia sẻ kiến thức sâu sắc về từ khóa Unicode la gi để tối ưu hóa nội dung trang web và chiến dịch tiếp thị trực tuyến. Bài viết cung cấp phương pháp tìm kiếm, phân tích và lựa chọn từ khóa phù hợp, cùng với chiến lược và công cụ hữu ích. Hy vọng thông tin này sẽ giúp bạn xây dựng chiến lược thành công và thu hút lưu lượng người dùng. Cảm ơn sự quan tâm và hãy tiếp tục theo dõi blog để cập nhật kiến thức mới nhất.

Is Unicode a 16-bit encoding?

Bạn Đang Xem: Tìm hiểu Unicode

Nếu lời đáp bạn chọn là Đúng, xin chúc mừng, bạn đã sai, đừng buồn vì ít ra bạn đã sở hữu một đồng chí là mình =))

Một điều mà nhiều người đến nay vẫn nhầm tưởng là Unicode sử dụng 16 bit để mã hóa, bởi vậy nó chỉ có thể mã hóa tối đa 65536 ký tự. Điều này hoàn toàn không xác thực.

Thực ra, phiên bản trước nhất của Unicode đúng là sử dụng 16 bit để mã hóa, từ thời điểm năm 1991 đến 1995. Nhưng từ khi Unicode 2.0 ra đời (06/1996), nó không còn sử dụng chỉ 16 bit để mã hóa nữa. Chuẩn Unicode mã hóa ký tự trong dải từ U+0000 đến U+10FFFF, tức là gồm có không gian mã khoảng tầm 21 bit. Tùy vào phương thức mã hóa được sử dụng (UTF-8, UTF-16, UTF-32), mỗi ký tự sẽ tiến hành trình diễn bởi một 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ỉ một đơ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 xuất hiện bất kỳ hệ nào lưu trữ được đầy đủ mọi ký tự. Nổi trội nhất chắc có nhẽ là ASCII, bảng mã dựa trên vần âm Latin được sử dụng trong tiếng Anh tiến bộ.

Xác thực thì ASCII dùng 7 bit trình diễn với 7 số nhị phân (thập phân từ 0 đến 127). Từ 32 đến 127 là những ký tự in được, tức là hiển thị được, ví dụ ‘ ‘ là 32, vần âm ‘A’ là 65. Mã dưới 32 được dùng để làm trình diễn ký tự điều khiển và tinh chỉnh (control character), ví dụ như nút ESC, Backspace.

Rõ ràng chỉ với 7, thậm chi là 8 bit, bạn chỉ trình diễn được tối đa 256 ký tự, từng đó quá đủ với tiếng Anh, tuy nhiên với tiếng nói khác thì không thể. Vậy các hệ mã hóa khác thì sao? Những hệ mã hóa này lại xung đột với nhau. Ví dụ cả hai đều cùng sử dụng một số để trình diễn hai ký tự khác biệt, hoặc lại dùng hai số khác nhau để trình diễn cùng một ký tự. Mỗi một máy tính đều tương trợ nhiều chuẩn mã hóa, chính vì vậy mà mỗi một khi tài liệu được trao đổi giữa các 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à xử lý vấn đề này. Nó cung cấp một trình diễn số duy nhất cho từng một ký tự, mà không cần quan tâm đến nền tảng, Khóa học hay tiếng nói là gì. Chuẩn Unicode (Unicode Standard) cung cấp một phương thức nhất quán để mã hóa toàn bộ tiếng nói viết trên thế giới. Để mã ký tự trông đơn giản và hiệu quả, nó sẽ gán một ký tự với một số duy nhất. Chuẩn Unicode tương trợ 3 hình thức mã hóa như tôi đã nói ở trên, gồm có UTF-8, UTF-16 và UTF-32, mã hóa cùng một bộ ký tự, dĩ nhiên.

Bảng mã Unicode

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

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

Mỗi ký tự được gán một tên duy nhất để phân biệt nó với ký tự khác. Chẳng hạn, U+0041 được gán tên là “LATIN CAPITAL LETTER A”. U+0A1B được gán với tên “GURMUKHI LETTER CHA”.

Lấy ví dụ một xâu ký tự:

Hello

trong Unicode, xâu ký tự này tương ứng với 5 điểm mã (lưu ý là 5 điểm mã chứ không phải 5 byte)

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

Số vần âm mà Unicode có thể khái niệm là không giới hạn, trên thực tế nó vượt xa số lượng 65536. phiên bản Unicode tiên tiến nhất là 9.0.0, trình diễn tổng số 128172 ký tự.

Xem Thêm : Ps là gì? Tại sao người ta thích dùng P/s trên mạng xã hội?

Một số thuật ngữ thường dùng trong Unicode như: không gian mã (code space), plane, code unit, block…

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

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

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

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

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

Tiếng Việt của mình thì dùng các ký tự trong block Basic Latin, để trình diễn các ký tự không dấu, như “a”, “A”. Còn các ký tự có dấu như “á”, “ấ”, “Ớ” thì nằm trong block Latin-1 Supplement, Latin Extended-B và Latin Extended Additional. tin tức về các Unicode block các chúng ta có thể tra cứu ở đây.

http://unicode-table.com/en/

Các 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ự (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. Mỗi điểm mã được trình diễn trực tiếp bằng một đơn vị mã 32 bit

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

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

Trong nội dung 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 sử dụng phổ thông nhất hiện nay. Hiểu được cách UTF-8 mã hóa sẽ giúp tất cả chúng ta có cái nhìn toàn diện hơn về việc mã hóa ký tự. Một số ưu điểm của nó:

  1. UTF-8 có thể trình diễn được mọi điểm mã Unicode
  2. Nó tương thích của ASCII
  3. Nó tiết kiệm ngân sách và chi phí không gian hơn so với những kiểu mã hóa đồng đội của nó như UTF-16 hay UTF-32. Ký tự mã hóa theo phong cách UTF-8 có thể nằm trong khoảng tầm từ 1-4 byte. Với văn bản tiếng Anh thông thường thì chỉ việc sử dụng 1-2 byte để trình diễn một ký tự.
  4. UTF-8 không yêu cầu sử dụng BOM (byte order mark)

Để thực sự hiểu cách UTF-8 encoding thao tác, tất 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. Với ký tự chỉ có một byte (hồ hết là ASCII), bit trước nhất sẽ luôn là 0 để tương thích với ASCII
  2. Với ký tự multi-byte, byte trước nhất sẽ khai mạc với từ 2-4 số 1 để trình diễn số byte ký tự sẽ dùng, theo sau là một số 0
  3. Phần bit sót lại trong byte trước nhất và những byte tiếp theo được dùng để làm điền những bit trình diễn điểm mã, ngoại trừ việc mỗi byte tiếp theo sẽ khai mạc với 10

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

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

Thêm vào đó ở mục 3 mình có đề cập là những byte sau byte trước nhất luôn luôn được khai mạc với 10. Vì vậy với 3 bit trước nhất của byte thứ nhất là 110, 2 bit trước nhất của byte thứ hai là 10, tất cả chúng ta đã dùng 5 bit để sử dụng cho định dạng kiểu mã hóa, lúc này chỉ với 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 tất cả chúng ta chỉ việc lấp vào số bit còn thừa đã tính ở trên, cắt từ trái sang phải. Như vậy byte trước nhất sẽ là

11000010

Xem Thêm : Ancol là gì? Tính chất, điều chế, ứng dụng của ancol – VietChem

byte tiếp theo sẽ là

10100011

Nếu vẫn còn mập mờ thì chúng ta có thể xem thêm ví dụ minh họa ở đây, cực kỳ dễ hiểu.

https://en.wikipedia.org/wiki/UTF-8#Examples

Ứng dụng

Vậy là thời điểm này chắc các bạn đã và đang 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 vướng mắc sau xem sao nhé (à trên editor nhớ lưu lại với 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ứ hai thì đơn giản rồi, strlen đo chiều dài xâu ký tự dựa trên số byte, còn mb_strlen đo chiều dài dựa trên encoding, bộ ký tự tiếng Nhật mã hóa theo UTF-8 thì nên 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ị trí index, nên đương nhiên kết quả sẽ lỗi, vì trình duyệt cũng như bộ giải thuật không hiểu đây là cái gì, bởi nếu chuyển sang hệ nhị phân thì nó là 11100011, không trùng với bất kể ký tự nào (facepalm)

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

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

sẽ cho output là

ký tự này còn có điểm mà Unicode là U+33C2 (có vẻ không liên quan lắm) =))

Câu thứ 5 và thứ 6, có nhẽ bạn cảm thấy hơi lạ, vì cùng là ký tự tiếng Việt mà lại sở hữu độ dài byte khác nhau, nguyên nhân là vì tiếng Việt mình sử dụng ký tự thuộc nhiều block khác nhau, có ở cả Basic Latin (vốn là ASCII, nên chỉ có thể có một byte), rồi Latin-1 Supplement, Latin Extended-B và Latin Extended Additional, nên nó có thể có độ dài từ một đến 3 byte, và kết quả strlen cũng thay đổi tùy theo ký tự ấy sử dụng bao nhiêu byte.

Vậy là xong, mong rằng qua nội dung bài viết này thì bạn cũng tồn tại cái nhìn rõ hơn về Unicode và xử lý ký tự bất kể là single-byte hay multi-byte. Thank you for reading!

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

You May Also Like

About the Author: v1000