Tiếng Trung, tiếng Nhật và tiếng Hàn. Đơn vị khối lượng dữ liệu và dung lượng bộ nhớ: kilobyte, megabyte, gigabyte...

(Và nó không phải về kích thước)

Elliott Rusty Harold
Xuất bản 25/09/2013

Dịch vụ sơ đồ trang web Google gần đây đã gây xôn xao cộng đồng XML khi nó bắt đầu yêu cầu tất cả các sơ đồ trang web phải được xuất bản độc quyền bằng UTF-8 Unicode. Google thậm chí không cho phép các mã hóa Unicode thay thế (chẳng hạn như UTF-16), chưa nói đến các mã hóa không phải Unicode như ISO-8859-1. Về mặt kỹ thuật, điều này có nghĩa là Google đang sử dụng một số loại trình phân tích cú pháp XML không tuân thủ tiêu chuẩn vì Khuyến nghị XML nêu rõ rằng "tất cả các bộ xử lý XML PHẢI chấp nhận mã hóa UTF-8 và UTF-16 Unicode 3.1". Tuy nhiên, đây có thực sự là một vấn đề?

UTF-8 có sẵn cho tất cả mọi người

Tính linh hoạt là lý do đầu tiên và thuyết phục nhất để chọn UTF-8. Mã hóa này có khả năng hoạt động với hầu hết mọi hệ thống chữ viết đang được sử dụng hiện nay. Một số khoảng trống vẫn còn, nhưng chúng ngày càng trở nên hiếm và hiện đang được lấp đầy. Phần lớn các hệ thống chữ viết vẫn chưa được khám phá cũng chưa được triển khai trong bất kỳ bộ ký tự nào khác và ngay cả khi chúng đã được triển khai thì cũng không có sẵn trong XML. TRONG kịch bản hay nhất chúng được triển khai bằng cách hack phông chữ được xây dựng dựa trên các bộ ký tự một byte như Latin-1. Hỗ trợ thực sự cho những hệ thống hiếm các chữ cái đầu tiên sẽ xuất hiện bằng Unicode (và có lẽ chỉ có ở Unicode và không ở nơi nào khác).

Tuy nhiên, đây chỉ là một trong những lập luận ủng hộ Unicode. Tại sao chọn UTF-8 thay vì UTF-16 hoặc các bảng mã Unicode khác? Một trong những lý do rõ ràng nhất là sự ủng hộ rộng rãi công cụ. Hầu như bất kỳ trình soạn thảo quan trọng nào có thể được sử dụng với XML đều hoạt động với UTF-8, bao gồm JEdit, BBEdit, Eclipse, emacs và thậm chí cả Sổ tay Windows(Sổ tay). Không có bảng mã Unicode nào khác có khả năng hỗ trợ công cụ rộng rãi như vậy giữa các tiện ích XML và không phải XML.

Trong một số trường hợp (chẳng hạn như BBEdit và Eclipse), UTF-8 không phải là bộ ký tự mặc định. Đã đến lúc thay đổi mặc định - tất cả các công cụ phải đi kèm với UTF-8 làm mã hóa mặc định. Cho đến khi điều đó xảy ra, chúng ta sẽ vẫn ở trong một vũng lầy gồm các tệp không tương thích về mặt chức năng và bị hỏng khi truyền qua ranh giới quốc gia, nền tảng và ngôn ngữ. Tuy nhiên, cho đến khi tất cả các chương trình có UTF-8 làm mã hóa mặc định, bạn có thể dễ dàng tự thay đổi cài đặt mặc định. Ví dụ, trong Eclipse, trong bảng General/Editors được hiển thị trong Hình 1, bạn có thể chỉ định rằng tất cả các tệp phải được mã hóa UTF-8. Bạn có thể nhận thấy rằng Eclipse "muốn" cài đặt MacRoman theo mặc định; tuy nhiên, nếu bạn cho phép điều này, các tập tin của bạn sẽ không biên dịch khi được gửi tới các lập trình viên đang chạy các máy tính đang chạy hệ thống Microsoft® Windows® và bất kỳ máy tính nào bên ngoài Hoa Kỳ và Tây Âu.

Hình 1. Thay đổi bộ ký tự mặc định trong Eclipse

Tất nhiên, để UTF-8 hoạt động, các nhà phát triển mà bạn chia sẻ tệp cũng phải sử dụng UTF-8; nhưng điều này không thành vấn đề. Không giống như MacRoman, UTF-8 không chỉ giới hạn ở một số hệ thống chữ viết và một nền tảng ít được sử dụng hơn. UTF-8 hoạt động tốt cho mọi người và mọi người. Tình hình hoàn toàn khác với MacRoman, Latin-1, SJIS và các bộ ký tự dân tộc truyền thống khác.

UTF-8 cũng hoạt động tốt hơn với các công cụ không yêu cầu dữ liệu nhiều byte. Các định dạng Unicode khác (chẳng hạn như UTF-16) thường chứa nhiều byte rỗng. Nhiều công cụ hiểu các byte này là phần cuối của tệp hoặc một số dấu phân cách đặc biệt khác, dẫn đến những hậu quả không mong muốn, không lường trước được và thường khó chịu. Ví dụ: nếu dữ liệu UTF-16 được tải "đơn giản" vào chuỗi C, thì chuỗi đó có thể bị cắt bớt ở byte thứ hai của ký tự ASCII đầu tiên. Các tệp UTF-8 chỉ chứa các số 0 thực sự cần phải là số 0. Tất nhiên, bạn không nên chọn những công cụ đơn giản như vậy để xử lý tài liệu XML. Tuy nhiên, các tài liệu thường kết thúc ở những vị trí khác thường trong các hệ thống truyền thống, nơi chưa ai thực sự xem xét hoặc hiểu rõ hậu quả của việc đổ rượu mới vào bầu rượu cũ. Trên các hệ thống không quen thuộc với Unicode và XML, các vấn đề ít có khả năng xảy ra khi sử dụng UTF-8 hơn khi làm việc với UTF-16 hoặc các bảng mã Unicode khác.

Thông số kỹ thuật nói gì

XML là tiêu chuẩn chính đầu tiên hỗ trợ đầy đủ UTF-8, nhưng đó mới chỉ là bước khởi đầu của một xu hướng. Các cơ quan tiêu chuẩn ngày càng khuyến nghị UTF-8. Ví dụ: URL chứa ký tự không phải ASCII trong một khoảng thời gian dàiđã là một vấn đề nan giải trên Internet. URL chạy trên PC chứa các ký tự không phải ASCII sẽ không thành công khi tải lên Nền tảng Mac và ngược lại. Vấn đề này chỉ được giải quyết gần đây khi Consortium toàn thế giới Web (W3C) và Lực lượng đặc nhiệm kỹ thuật Internet (IETF) đã đồng ý rằng tất cả các URL sẽ chỉ được mã hóa bằng UTF-8 và không có mã hóa nào khác.

Cả hai tổ chức (W3C và IETF) Gần đâyđã trở nên kiên quyết hơn trong việc chọn UTF-8 nói chung và đôi khi là mã hóa duy nhất. Trong tài liệu Mô hình ký tự W3C cho thế giới Web rộng 1.0: Cơ bản(Mô hình ký tự W3C cho World Wide Web 1.0: Khái niệm cơ bản) nêu rõ: “Khi cần bất kỳ mã hóa ký tự rõ ràng nào, mã hóa ký tự UTF-8, UTF-16 hoặc UTF-32 PHẢI được sử dụng. Mã hóa US-ASCII tương thích hướng lên với UTF-8 (chuỗi US-ASCII cũng là chuỗi UTF-8, xem ), vì vậy có thể sử dụng UTF-8 nếu cần khả năng tương thích US-ASCII." Trong thực tế, khả năng tương thích US-ASCII hữu ích đến mức nó thực tế là một yêu cầu. W3C giải thích một cách khôn ngoan: “Trong các tình huống khác, chẳng hạn như API, UTF-16 hoặc UTF-32 có thể phù hợp hơn. Lý do có thể việc lựa chọn một trong những mã hóa này liên quan đến hiệu quả xử lý nội bộ và khả năng tương tác với các quy trình khác."

Tôi có thể ủng hộ lập luận về tính hiệu quả của quá trình xử lý nội bộ. Ví dụ: biểu diễn bên trong của chuỗi ngôn ngữ Java™ dựa trên UTF-16, giúp tăng tốc đáng kể việc lập chỉ mục thành chuỗi. Tuy nhiên mã java không bao giờ hiển thị biểu diễn bên trong của nó cho các chương trình mà nó giao tiếp. Thay vào đó, java.io.Writer được sử dụng để liên lạc bên ngoài và bộ ký tự được chỉ định rõ ràng. Khi thực hiện lựa chọn này, bạn nên sử dụng UTF-8.

Các yêu cầu của IETF thậm chí còn rõ ràng hơn. Trong tài liệu Chính sách bộ ký tự của IETF(Chính sách bộ ký tự của IETF) nêu rõ:

Các giao thức PHẢI có khả năng sử dụng bộ ký tự UTF-8 cho tất cả văn bản, bao gồm bộ ký tự được mã hóa ISO 10646 kết hợp với sơ đồ mã hóa ký tự UTF-8 được xác định trong Phụ lục R (được xuất bản trong Bản sửa đổi 2).

Các giao thức CÓ THỂ chỉ định thêm cách sử dụng các bộ ký tự khác hoặc các sơ đồ mã hóa ký tự khác cho ISO 10646, chẳng hạn như UTF-16, nhưng việc không sử dụng UTF-8 là vi phạm chính sách này; sự vi phạm như vậy sẽ yêu cầu một số hình thức thủ tục sai lệch (Phần 9) với sự biện minh rõ ràng và thuyết phục trong tài liệu đặc tả giao thức trước khi bước vào hoặc tiếp tục con đường tiêu chuẩn.

Đối với các giao thức hiện có và các giao thức di chuyển dữ liệu từ các kho dữ liệu hiện có, một yêu cầu có thể là hỗ trợ các bộ ký tự khác hoặc thậm chí sử dụng mã hóa mặc định khác với UTF-8. Điều này có thể chấp nhận được, nhưng PHẢI có khả năng hỗ trợ UTF-8.

Thời điểm quan trọng: hỗ trợ cho các giao thức và tệp truyền thống có thể yêu cầu áp dụng các bộ ký tự và mã hóa khác ngoài UTF-8 trong một thời gian - tuy nhiên, tôi sẽ dẫm phải cổ họng bài hát riêng nếu tôi phải làm điều này. Mọi giao thức mới, mọi ứng dụng mới và mọi tài liệu mới phải sử dụng UTF-8.

Ngôn ngữ Trung Quốc, Nhật Bản và Hàn Quốc

Một quan niệm sai lầm phổ biến là UTF-8 là định dạng nén. Điều này về cơ bản là sai. Các ký tự trong phạm vi ASCII chỉ chiếm một nửa dung lượng trong UTF-8 so với một số bảng mã Unicode khác, đặc biệt là UTF-16. Tuy nhiên, một số biểu tượng yêu cầu tới 50% nhiều không gian hơnđể mã hóa UTF-8 - đặc biệt là các ký tự tiếng Trung, tiếng Nhật và tiếng Hàn (CJK).

Nhưng ngay cả khi bạn mã hóa XML CJK thành UTF-8, mức tăng kích thước thực tế so với UTF-16 có thể sẽ không đáng kể. Ví dụ: một tài liệu XML trên người Trung Quốc chứa nhiều ký tự ASCII như<, >, &, =, ", " và một khoảng trắng. Tất cả các ký tự này chiếm ít không gian hơn trong UTF-8 so với UTF-16. Tỷ lệ nén hoặc mở rộng chính xác thay đổi tùy theo từng tài liệu, nhưng trong mọi trường hợp, sự khác biệt khó có thể nhận thấy rõ ràng.

Cuối cùng, điều đáng chú ý là các hệ thống chữ tượng hình như tiếng Trung và tiếng Nhật có xu hướng “tiết kiệm” về số lượng ký tự so với các hệ thống chữ cái như Latin và Cyrillic. Một số lượng lớn các ký tự này yêu cầu ba byte trở lên cho mỗi ký tự để thể hiện đầy đủ các hệ thống chữ viết được chỉ định; điều này có nghĩa là các từ và câu giống nhau có thể được diễn đạt bằng cách sử dụng ít ký tự hơn so với các ngôn ngữ như tiếng Anh và tiếng Nga. Ví dụ: chữ tượng hình tiếng Nhật cho cây là æ¨. (Nó trông hơi giống gỗ). Chữ tượng hình này chiếm ba byte trong UTF-8, trong khi từ tiếng Anh “cây” bao gồm bốn chữ cái và chiếm bốn byte. Chữ tượng hình của tiếng Nhật cho khu rừng là æ- (hai cái cây cạnh nhau). Nó cũng chiếm ba byte trong UTF-8, trong khi từ tiếng Anh "grove" bao gồm năm chữ cái và chiếm năm byte. Chữ tượng hình Nhật Bản 森 (ba cây) vẫn chỉ có ba byte. Và từ tiếng Anh tương đương "rừng" có sáu.

Nếu bạn thực sự quan tâm đến việc nén, hãy nén XML bằng tiện ích zip hoặc gzip. UTF-8 được nén có thể sẽ có kích thước gần bằng UTF-16 đã nén bất kể sự khác biệt về kích thước ban đầu. Ban đầu kích thước lớn hơn một trong các tài liệu sẽ được bù đắp bằng độ dư thừa lớn hơn, điều này sẽ được loại bỏ bằng thuật toán nén.

độ tin cậy

Điều thú vị thực sự là, theo thiết kế, UTF-8 là định dạng đáng tin cậy hơn và dễ diễn giải hơn bất kỳ mã hóa văn bản nào khác được phát triển trước hoặc kể từ UTF-8. Đầu tiên, không giống như UTF-16, UTF-8 không có vấn đề về độ bền. UTF-8 Little-endian và Little-endian giống hệt nhau vì UTF-8 được định nghĩa bằng byte 8 bit thay vì các từ 16 bit. UTF-8 không có sự mơ hồ về thứ tự byte mà phải được giải quyết bằng cách sử dụng dấu thứ tự byte hoặc các phương pháp phỏng đoán khác.

Thậm chí nhiều hơn đặc điểm quan trọng UTF-8 không có trạng thái. Mỗi byte của luồng hoặc chuỗi UTF-8 đều rõ ràng. Trong UTF-8, bạn luôn biết mình đang ở đâu - nghĩa là, bạn có thể biết ngay từ một byte đơn xem đó có phải là ký tự một byte hay không, byte đầu tiên của ký tự byte kép, byte thứ hai của byte kép ký tự hoặc byte thứ hai, thứ ba hoặc thứ tư của ký tự ba hoặc bốn byte. (Đây không phải là tất cả các khả năng, nhưng thông tin được cung cấp sẽ giúp bạn có được ý tưởng chung). Trong UTF-16, không phải lúc nào bạn cũng biết liệu byte "0x41" có đại diện cho chữ cái "A" hay không. Đôi khi điều này đúng, và đôi khi không. Bạn cần có đủ khả năng theo dõi trạng thái để biết mình đang ở đâu trong luồng. Nếu bất kỳ byte đơn nào bị mất thì tất cả dữ liệu tiếp theo từ thời điểm đó trở đi sẽ bị hỏng. Trong UTF-8, các byte bị mất hoặc bị hỏng được phát hiện ngay lập tức và không làm hỏng dữ liệu khác.

Mã hóa UTF-8 không lý tưởng cho tất cả các ứng dụng. Các ứng dụng yêu cầu quyền truy cập ngẫu nhiên vào các chỉ mục cụ thể trong tài liệu có thể hoạt động nhanh hơn khi sử dụng một số mã hóa có chiều rộng cố định như UCS2 hoặc UTF-32. (UTF-16 là mã hóa có độ rộng thay đổi khi tính đến các cặp thay thế). Tuy nhiên, xử lý XML không phải là một trong những ứng dụng đó. Đặc tả XML thực sự yêu cầu các trình phân tích cú pháp bắt đầu phân tích cú pháp ở byte đầu tiên tài liệu XML và tiếp tục phân tích đến cùng và tất cả các trình phân tích cú pháp hiện có đều hoạt động theo cách này. Việc tăng tốc truy cập ngẫu nhiên sẽ không giúp xử lý XML theo bất kỳ cách nào; vì vậy mặc dù đây có thể là lý do chính đáng để sử dụng một số mã hóa khác trong cơ sở dữ liệu hoặc hệ thống khác nhưng nó không liên quan đến XML.

Phần kết luận

Trong một thế giới ngày càng quốc tế hóa, với ranh giới ngôn ngữ và chính trị ngày càng mờ nhạt, các bộ ký tự địa phương đang trở nên không thể sử dụng được. Unicode là bộ ký tự duy nhất có thể được sử dụng ở tất cả các ngôn ngữ trên thế giới. UTF-8 là một triển khai Unicode thích hợp:

  • có tính năng hỗ trợ nhiều công cụ, bao gồm khả năng tương thích tốt nhất với các hệ thống ASCII truyền thống;
  • đơn giản và hiệu quả để xử lý;
  • chống tham nhũng dữ liệu;
  • là nền tảng độc lập.

Đã đến lúc ngừng tranh luận về bộ ký tự và bảng mã - hãy chọn UTF-8 và kết thúc cuộc tranh luận.

Về mặt lý thuyết, giải pháp cho những vấn đề này đã có từ lâu. Nó được gọi là Unicode (Unicode). bảng mã Unicode là bảng mã hóa trong đó 2 byte được sử dụng để mã hóa từng ký tự, tức là 16 bit. Dựa trên bảng như vậy, N=2 16 =65.536 ký tự có thể được mã hóa.

Unicode bao gồm hầu hết tất cả các chữ viết hiện đại, bao gồm: tiếng Ả Rập, tiếng Armenia, tiếng Bengali, tiếng Miến Điện, tiếng Hy Lạp, tiếng Gruzia, tiếng Devanagari, tiếng Do Thái, tiếng Cyrillic, tiếng Coptic, tiếng Khmer, tiếng Latin, tiếng Tamil, tiếng Hangul, tiếng Hán (Trung Quốc, Nhật Bản, Hàn Quốc), Cherokee, Ethiopia, Tiếng Nhật (katakana, hiragana, kanji) và những ngôn ngữ khác.

Vì mục đích học thuật, nhiều chữ viết lịch sử đã được thêm vào, bao gồm: chữ tượng hình Hy Lạp cổ đại, chữ tượng hình Ai Cập, chữ hình nêm, chữ viết của người Maya và bảng chữ cái Etruscan.

Unicode cung cấp một loạt các ký hiệu và chữ tượng hình toán học và âm nhạc.

Có hai phạm vi mã cho các ký tự Cyrillic trong Unicode:

Chữ Cyrillic (#0400 - #04FF)

Bổ sung Cyrillic (#0500 - #052F).

Nhưng tiêm bảng bảng mã Unicodeở dạng thuần túy của nó bị hạn chế vì lý do nếu mã của một ký tự chiếm không phải một byte mà là hai byte, thì việc lưu trữ văn bản sẽ tốn gấp đôi không gian đĩa và để truyền nó qua các kênh liên lạc thì phải mất gấp đôi thời gian.

Vì vậy, trong thực tế hiện nay, cách biểu diễn Unicode UTF-8 (Định dạng chuyển đổi Unicode) phổ biến hơn. UTF-8 cung cấp khả năng tương thích tốt nhất với các hệ thống sử dụng ký tự 8 bit. Văn bản chỉ bao gồm các ký tự được đánh số nhỏ hơn 128 sẽ được chuyển đổi thành văn bản ASCII thuần túy khi được viết bằng UTF-8. Các ký tự Unicode khác được biểu diễn dưới dạng chuỗi có độ dài từ 2 đến 4 byte. Nhìn chung, do các ký tự phổ biến nhất trên thế giới, bảng chữ cái Latinh, vẫn chiếm 1 byte trong UTF-8, nên cách mã hóa này tiết kiệm hơn so với Unicode thuần túy.

    Trong mã hóa văn bản tiếng anh Chỉ có 26 chữ cái trong bảng chữ cái Latinh và 6 dấu chấm câu khác được sử dụng. Trong trường hợp này, văn bản chứa 1000 ký tự có thể được đảm bảo nén mà không làm mất thông tin về kích thước:

    Từ điển của Ellochka - "kẻ ăn thịt người" (nhân vật trong tiểu thuyết "Mười hai chiếc ghế") gồm 30 từ. Bao nhiêu bit là đủ để mã hóa toàn bộ từ vựng Ellochki? Tùy chọn: 8, 5, 3, 1.

    1. Đơn vị khối lượng dữ liệu và dung lượng bộ nhớ: kilobyte, megabyte, gigabyte...

Vì vậy, chúng tôi phát hiện ra rằng trong hầu hết mã hóa hiện đại 1 byte được phân bổ để lưu trữ một ký tự văn bản trên phương tiện điện tử. Những thứ kia. Dung lượng (V) bị chiếm bởi dữ liệu trong quá trình lưu trữ và truyền (tệp, tin nhắn) được đo bằng byte.

Khối lượng dữ liệu (V) – số byte cần thiết để lưu trữ chúng trong bộ nhớ của phương tiện lưu trữ điện tử.

Bộ nhớ phương tiện lại bị hạn chế dung tích, I E. khả năng chứa một khối lượng nhất định. Dung lượng bộ nhớ phương tiện truyền thông điện tử tất nhiên thông tin cũng được đo bằng byte.

Tuy nhiên, byte là đơn vị nhỏ của khối lượng dữ liệu; đơn vị lớn hơn là kilobyte, megabyte, gigabyte, terabyte...

Cần nhớ rằng các tiền tố “kilo”, “mega”, “giga”... không có trong trong trường hợp này số thập phân.

Vì vậy, “kilo” trong từ “kilobyte” không có nghĩa là “nghìn”, tức là không có nghĩa là “10 3”. Bit là một đơn vị nhị phân, và vì lý do này trong khoa học máy tính, sẽ thuận tiện hơn khi sử dụng các đơn vị là bội số của số “2” thay vì số “10”. 3 1 byte = 2 10 =8 bit, 1 kilobyte = 2= 1024 byte. TRONG nhị phân

1 kilobyte = &10000000000 byte. Những thứ kia. “kilo” ở đây biểu thị số gần nhất với một nghìn, cũng là lũy thừa của 2, tức là. đó là một số "làm tròn" trong hệ thống nhị phân

Tính toán

Bảng 10.

Đặt tên

chỉ định

Giá trị tính bằng byte

kilobyte

megabyte

2 10 Kb = 2 20 b

gigabyte

2 10 Mb = 2 30 b

terabyte

1 099 511 627 776 b

Vì đơn vị đo thể tích và dung tích phương tiện lưu trữ là bội số của 2 chứ không phải bội số của 10, hầu hết các bài toán trong chủ đề này sẽ dễ giải hơn khi các giá trị xuất hiện trong chúng được biểu thị bằng lũy ​​thừa của 2. Hãy xem xét một ví dụ về bài toán như vậy và cách giải của nó:

Tệp văn bản lưu trữ 400 trang văn bản. Mỗi trang chứa 3200 ký tự. Nếu sử dụng mã hóa KOI-8 (8 bit cho mỗi ký tự), thì kích thước tệp sẽ là:

Giải pháp

    Xác định tổng số ký tự trong một tệp văn bản. Trong trường hợp này, chúng tôi biểu thị các số là bội số của 2 dưới dạng lũy ​​thừa của 2, tức là. thay vì 4, hãy viết 2 2, v.v. Bảng 7 có thể được sử dụng để xác định mức độ.

nhân vật.

2) Theo điều kiện của bài toán, 1 ký tự chiếm 8 bit, tức là 1 byte => tệp mất 2 7 *10000 byte.

3) 1 kilobyte = 2 10 byte => kích thước tệp tính bằng kilobyte là:

.

    Có bao nhiêu bit trong một kilobyte?

    &10000000000000.

    1 MB bằng bao nhiêu?

    1024 byte;

    1024 kilobyte;

  • 1000000 byte.

    Có bao nhiêu bit trong một tin nhắn một phần tư kilobyte? Tùy chọn: 250, 512, 2000, 2048.

    Âm lượng tập tin văn bản 640 Kb. Tệp chứa một cuốn sách được gõ trung bình 32 dòng trên trang và 64 ký tự trong một dòng. Cuốn sách có bao nhiêu trang: 160, 320, 540, 640, 1280?

    Hồ sơ nhân viên được lưu giữ 8 Mb. Mỗi người trong số họ chứa 16 trang ( 32 dòng bởi 64 ký tự trong một dòng). Có bao nhiêu nhân viên trong tổ chức: 256; 512; 1024; 2048?

Bài đăng này dành cho những người không hiểu UTF-8 là gì nhưng muốn hiểu nó và các tài liệu có sẵn thường đề cập rất rộng rãi về vấn đề này. Ở đây tôi sẽ cố gắng mô tả nó theo cách mà tôi muốn ai đó nói với tôi điều này trước đây. Vì tôi thường bối rối trong đầu về UTF-8.

Một vài quy tắc đơn giản

  1. Vì vậy, UTF-8 là trình bao bọc cho Unicode. Đây không phải là mã hóa ký tự riêng biệt, nó là Unicode "được bọc". Bạn có thể biết hoặc đã nghe nói về mã hóa Base64 - nó có thể gói dữ liệu nhị phân thành các ký tự có thể in được. Chà, UTF-8 giống với Base64 cho Unicode giống như Base64 dành cho dữ liệu nhị phân. Thời gian này. Nếu bạn hiểu điều này, thì nhiều điều sẽ trở nên rõ ràng. Và nó, giống như Base64, được coi là giải quyết được vấn đề tương thích về ký tự (Base64 được phát minh cho email, để truyền tệp qua thư, trong đó tất cả các ký tự đều có thể in được)
  2. Hơn nữa, nếu mã hoạt động với UTF-8, thì bên trong nó vẫn hoạt động với bảng mã Unicode, tức là đâu đó sâu bên trong có các bảng ký tự chính xác là các ký tự Unicode. Đúng, bạn có thể không có bảng ký tự Unicode nếu bạn chỉ cần đếm xem có bao nhiêu ký tự trong một dòng chẳng hạn (xem bên dưới)
  3. UTF-8 được tạo ra nhằm mục đích giúp các chương trình cũ và máy tính ngày nay có thể hoạt động bình thường với các ký tự Unicode, như với các bảng mã cũ như KOI8, Windows-1251, v.v. Trong UTF-8 không có byte nào có số 0, tất cả đều là byte là từ 0x01 - 0x7F, như ASCII thông thường hoặc 0x80 - 0xFF, cũng hoạt động trong các chương trình được viết bằng C, giống như nó hoạt động với các ký tự không phải ASCII. Đúng, đối với hoạt động chính xác có ký hiệu thì chương trình phải biết bảng Unicode.
  4. Bất kỳ thứ gì có bit quan trọng thứ 7 trong một byte (đếm các bit từ 0) UTF-8 đều là một phần của luồng được mã hóa Unicode.

UTF-8 từ bên trong

Nếu bạn biết hệ thống bit thì bạn bắt đầu nhé nhắc nhở ngắn gọn dưới dạng mã hóa UTF-8:

Byte đầu tiên của ký tự Unicode trong UTF-8 bắt đầu bằng một byte trong đó bit thứ 7 luôn là một và bit thứ 6 luôn là một. Hơn nữa, trong byte đầu tiên, nếu bạn nhìn vào các bit từ trái sang phải (thứ 7, thứ 6, v.v. cho đến 0), thì có nhiều đơn vị bằng số byte, bao gồm cả byte đầu tiên, được sử dụng để mã hóa một ký tự Unicode. Chuỗi những cái kết thúc bằng số 0. Và sau đó là các bit của ký tự Unicode. Các bit còn lại của ký tự Unicode rơi vào byte thứ hai hoặc thậm chí thứ ba (tối đa là ba, xem lý do - xem bên dưới). Các byte còn lại, ngoại trừ byte đầu tiên, luôn bắt đầu bằng '10' và sau đó là 6 bit của phần tiếp theo của ký tự Unicode.

Ví dụ

Ví dụ: có byte 110 10000 và thứ hai 10 011110 . Cái đầu tiên bắt đầu bằng '110' - điều này có nghĩa là hai lần một - sẽ có hai byte của luồng UTF-8 và byte thứ hai, giống như tất cả các byte khác, bắt đầu bằng '10'. Và hai byte này mã hóa một ký tự Unicode, bao gồm 10100 bit từ phần đầu tiên + 101101 từ phần thứ hai -> 10000011110 -> 41Eở dạng thập lục phân, hoặc U+041E bằng cách viết các ký hiệu Unicode. Đây là biểu tượng của chữ O lớn của Nga.

Byte tối đa cho mỗi ký tự là bao nhiêu?

Ngoài ra, hãy xem UTF-8 cần bao nhiêu byte tối đa để mã hóa 16 bit mã hóa Unicode. Byte thứ hai trở lên luôn có thể chứa tối đa 6 bit. Điều này có nghĩa là nếu bạn bắt đầu với byte cuối cùng thì hai byte sẽ đi chính xác (thứ 2 và thứ ba) và byte đầu tiên phải bắt đầu bằng '1110' để mã hóa ba byte. Điều này có nghĩa là byte đầu tiên trong phiên bản này có thể mã hóa tối đa 4 bit đầu tiên của ký tự Unicode. Hóa ra 4 + 6 + 6 = 16 byte. Hóa ra UTF-8 có thể có 2 hoặc 3 byte cho mỗi ký tự Unicode (không thể, vì không cần mã hóa 6 bit (8 - 2 bit '10') - chúng sẽ ký tự ASCII. Đây là lý do tại sao byte đầu tiên của UTF-8 không bao giờ có thể bắt đầu bằng '10').

Phần kết luận

Nhân tiện, nhờ mã hóa này, bạn có thể lấy bất kỳ byte nào trong luồng và xác định xem byte đó có phải là ký tự Unicode hay không (nếu bit thứ 7 có nghĩa không phải là ASCII), nếu vậy thì đó có phải là byte đầu tiên trong luồng UTF-8 không hoặc không phải là số đầu tiên (nếu '10' có nghĩa không phải là số đầu tiên), nếu không phải là số đầu tiên thì chúng ta có thể di chuyển ngược byte byte để tìm mã UTF-8 đầu tiên (sẽ có số 1 ở bit thứ 6) hoặc di chuyển đến bên phải và bỏ qua tất cả '10' byte để tìm ký hiệu tiếp theo. Nhờ mã hóa này, các chương trình cũng có thể đếm số lượng ký tự trong một dòng mà không cần biết Unicode (dựa trên byte UTF-8 đầu tiên, tính độ dài của ký tự tính bằng byte). Nói chung, nếu bạn nghĩ về nó, mã hóa UTF-8 được phát minh rất thông minh và đồng thời rất hiệu quả.

Unicode hỗ trợ hầu hết các bộ ký tự hiện có. Hình thức tốt nhất Mã hóa của bộ ký tự Unicode là UTF-8. Nó có tính năng tương thích ASCII, khả năng chống tham nhũng, hiệu quả và dễ xử lý. Nhưng điều đầu tiên trước tiên.

Các hình thức mã hóa

Máy tính hoạt động với các con số không chỉ là các đối tượng toán học trừu tượng mà còn là sự kết hợp của các đơn vị lưu trữ và xử lý thông tin. kích thước cố định- byte và từ 32 bit. Tiêu chuẩn mã hóa cần tính đến điều này khi xác định phương pháp biểu diễn

= 1024 byte. hệ thống máy tính số nguyên được lưu trữ ở các vị trí bộ nhớ 8 bit (1 byte), 16 bit hoặc 32 bit. Mỗi dạng mã hóa Unicode chỉ định chuỗi vị trí bộ nhớ nào biểu thị số nguyên tương ứng với một ký tự cụ thể. Tiêu chuẩn bao gồm ba hình dạng khác nhau Mã hóa ký tự Unicode: khối 8, 16 và 32 bit. Theo đó, chúng được gọi là UTF-8, UTF-16 và UTF-32. Tên UTF là viết tắt của Định dạng chuyển đổi Unicode. Mỗi dạng trong số ba dạng mã hóa đều là một phương tiện như nhau để biểu diễn các ký tự Unicode và có những ưu điểm trong khu vực khác nhau các ứng dụng.

Những bảng mã này có thể được sử dụng để thể hiện tất cả các ký tự Unicode. Vì vậy, chúng hoàn toàn tương thích với các giải pháp theo nhiều lý do khác nhau sử dụng các dạng mã hóa khác nhau. Mỗi mã hóa có thể được chuyển đổi duy nhất sang một trong hai mã còn lại mà không mất dữ liệu.

Nguyên tắc không chồng chéo

Mỗi dạng mã hóa Unicode được thiết kế để tránh chồng chéo. Ví dụ: Windows-932 tạo các ký tự từ một hoặc hai byte mã. Độ dài của chuỗi phụ thuộc vào byte đầu tiên, do đó các giá trị của byte đầu tiên trong chuỗi gồm hai byte và một byte đơn không trùng nhau. Tuy nhiên, ý nghĩa của byte đơn và byte cuối của chuỗi có thể giống nhau. Điều này có nghĩa là, ví dụ, khi tìm kiếm ký tự D (mã 44), bạn có thể tìm nhầm nó nằm trong phần thứ hai của chuỗi hai byte ký tự “D” (mã 84 44). Để tìm ra chuỗi nào đúng, chương trình phải tính đến các byte trước đó.

Tình hình trở nên phức tạp hơn nếu byte đầu và byte cuối khớp nhau. Điều này có nghĩa là để loại bỏ sự mơ hồ, việc tìm kiếm ngược sẽ được thực hiện cho đến khi đạt đến phần đầu của văn bản hoặc một chuỗi mã rõ ràng. Điều này không những không hiệu quả mà còn không được bảo vệ khỏi lỗi có thể xảy ra, vì một byte sai cũng đủ khiến toàn bộ văn bản không thể đọc được.

Định dạng chuyển đổi Unicode tránh được vấn đề này vì các giá trị đơn vị lưu trữ ở đầu, cuối và đơn vị lưu trữ đơn không giống nhau. Điều này làm cho tất cả các bảng mã Unicode phù hợp cho việc tìm kiếm và so sánh, không bao giờ tạo ra kết quả sai do trùng khớp. các bộ phận khác nhau mã ký tự. Việc các dạng mã hóa này tôn trọng nguyên tắc không chồng chéo giúp phân biệt chúng với các dạng mã hóa Đông Á nhiều byte khác.

Một khía cạnh khác của việc không chồng chéo là mỗi ký tự đều có ranh giới được xác định rõ ràng. Điều này giúp loại bỏ nhu cầu quét số lượng ký tự trước đó không xác định. Tính năng này mã hóa đôi khi được gọi là tự đồng bộ hóa. Việc làm hỏng một đơn vị mã sẽ chỉ làm hỏng một ký tự, không ảnh hưởng đến các ký hiệu xung quanh. Ở định dạng chuyển đổi 8 bit, nếu con trỏ tham chiếu đến một byte bắt đầu bằng 10xxxxxx (ở dạng nhị phân), thì sẽ mất một đến ba dấu vết quay lại để tìm phần đầu của ký tự.

Tính nhất quán

Hiệp hội Unicode hỗ trợ đầy đủ cả 3 dạng mã hóa. Điều quan trọng là không so sánh UTF-8 và Unicode, vì tất cả các định dạng chuyển đổi đều là các phương án hợp pháp như nhau của các dạng mã hóa ký tự tiêu chuẩn Unicode.

Hướng byte

Để biểu thị ký tự UTF-32, bạn cần một đơn vị mã 32 bit, giống như Unicode. UTF-16 - một đến hai đơn vị 16 bit. Và UTF-8 sử dụng tối đa 4 byte.

Mã hóa UTF-8 được thiết kế để tương thích với các hệ thống định hướng byte. dựa trên ASCII. Hầu hết phần mềm hiện có và thực hành công nghệ thông tin thời gian dài dựa vào việc biểu diễn các ký tự dưới dạng một chuỗi byte. Nhiều giao thức dựa vào tính bất biến và sử dụng hoặc tránh các ký tự điều khiển đặc biệt. Một cách đơn giản Unicode có thể được điều chỉnh cho phù hợp với những tình huống như vậy bằng cách sử dụng mã hóa 8 bit để biểu thị các ký tự Unicode tương đương với bất kỳ hoặc ký tự điều khiển nào. Đây là mục đích mã hóa UTF-8.

Chiều dài thay đổi

UTF-8 - mã hóa chiều dài thay đổi, bao gồm các đơn vị lưu trữ thông tin 8 bit, các bit quan trọng nhất trong đó cho biết mỗi byte riêng lẻ thuộc về phần nào của chuỗi. Một phạm vi giá trị được dành riêng cho phần tử đầu tiên của chuỗi mã, phạm vi giá trị còn lại dành cho phần tử tiếp theo. Điều này đảm bảo rằng mã hóa không bị chồng chéo.

ASCII

Mã hóa UTF-8 được hỗ trợ đầy đủ mã ASCII(0x00-0x7F). Điều này có nghĩa là các ký tự Unicode U+0000-U+007F được chuyển đổi thành một byte đơn 0x00-0x7F của UTF-8 và do đó không thể phân biệt được với ASCII. Hơn nữa, để tránh sự mơ hồ, các giá trị 0x00-0x7F không còn được sử dụng trong bất kỳ byte nào của biểu diễn ký tự Unicode. Để mã hóa các ký tự không phải chữ tượng hình ngoài ASCII, một chuỗi hai byte được sử dụng. Các ký tự trong phạm vi U+0800-U+FFFF được biểu thị bằng ba byte và các ký tự bổ sung có mã lớn hơn U+FFFF yêu cầu bốn byte.

Khu vực ứng dụng

Mã hóa UTF-8 thường được ưu tiên trong HTML và các giao thức tương tự.

XML đã trở thành tiêu chuẩn đầu tiên hỗ trợ đầy đủ Mã hóa UTF-8. Các tổ chức tiêu chuẩn hóa cũng khuyến nghị nó. Vấn đề hỗ trợ trong URL các ký tự không phải ASCII đã được quyết định khi tập đoàn W3C và nhóm kỹ thuật IETF đồng ý mã hóa mọi thứ độc quyền bằng UTF-8.

Khả năng tương thích ASCII giúp việc chuyển đổi trở nên dễ dàng phần mềm. Hầu hết các trình soạn thảo văn bản đều hoạt động với UTF-8, bao gồm JEdit, Emacs, BBEdit, Eclipse và Notepad. hệ điều hành Các cửa sổ. Không có dạng mã hóa Unicode nào khác có thể tự hào về khả năng hỗ trợ công cụ như vậy.

Ưu điểm của mã hóa là nó bao gồm một chuỗi byte. Chuỗi UTF-8 dễ dàng làm việc với C và các ngôn ngữ lập trình khác. Đây là hình thức mã hóa duy nhất không yêu cầu khai báo BOM hoặc mã hóa trong XML.

Tự đồng bộ hóa

Trong môi trường sử dụng xử lý ký tự 8 bit, so với các mã hóa đa byte khác, UTF-8 có những ưu điểm sau:

  • Byte đầu tiên của chuỗi mã chứa thông tin về độ dài của nó. Điều này cải thiện hiệu quả của tìm kiếm trực tiếp.
  • Việc tìm kiếm phần đầu của một ký tự dễ dàng hơn vì byte bắt đầu được giới hạn trong một phạm vi giá trị cố định.
  • Không có giao điểm giá trị byte.

So sánh lợi ích

Mã hóa UTF-8 nhỏ gọn. Nhưng khi dùng để mã hóa các ký tự Đông Á (tiếng Trung, tiếng Nhật, tiếng Hàn, sử dụng ký tự tiếng Trung) thì sử dụng chuỗi 3 byte. Ngoài ra, mã hóa UTF-8 còn kém hơn các dạng mã hóa khác về tốc độ xử lý. Và việc sắp xếp chuỗi nhị phân tạo ra kết quả tương tự như sắp xếp nhị phân của Unicode.

Sơ đồ mã hóa ký tự

Sơ đồ mã hóa ký tự bao gồm một dạng mã hóa ký tự và sự sắp xếp các đơn vị mã theo từng byte. Để xác định sơ đồ mã hóa, tiêu chuẩn Unicode sử dụng dấu thứ tự byte hàng đầu (BOM).

Bằng cách bật BOM trong UTF-8, chức năng của nhãn bị giới hạn ở việc chỉ cho biết dạng mã hóa sẽ được sử dụng. UTF-8 không gặp vấn đề gì khi xác định thứ tự byte vì kích thước đơn vị mã hóa của nó là một byte. Việc sử dụng BOM cho hình thức mã hóa này không bắt buộc và không được khuyến khích. BOM có thể xuất hiện trong các văn bản được chuyển đổi từ các bảng mã khác sử dụng dấu thứ tự byte hoặc cho chữ ký mã hóa UTF-8. Biểu thị một chuỗi 3 byte EF 16 BB 16 BF 16.

Cách đặt mã hóa UTF-8

Đặt thành UTF-8 bằng mã sau:

˂meta http-equiv="Content-Type" content="text/html; charset=utf-8"˃

= 1024 byte. Mã hóa PHP UTF-8 được đặt bằng hàm header() ở đầu tệp sau khi đặt giá trị mức lỗi:

error_reporting(-1);

Bộ ký tự=utf-8");

Để kết nối với cơ sở dữ liệu Dữ liệu MySQL Mã hóa UTF-8 được đặt như thế này:

mysql_set_charset("utf8");

Trong các tệp CSS, mã hóa ký tự UTF-8 được chỉ định như sau:

@charset "utf-8";

Khi lưu các loại tệp, mã hóa UTF-8 không có BOM được chọn, nếu không trang web sẽ không hoạt động. Để thực hiện việc này, trong chương trình DreamWeave, bạn cần chọn mục menu “Sửa đổi - Thuộc tính trang - Tiêu đề/Mã hóa”, thay đổi mã hóa thành UTF-8. Sau đó, bạn nên tải lại trang, bỏ chọn hộp kiểm “Bật chữ ký Unicode (BOM)” và áp dụng các thay đổi. Nếu bất kỳ văn bản nào trên một trang hoặc trong cơ sở dữ liệu được nhập bằng một dạng mã hóa khác thì văn bản đó phải được nhập lại hoặc mã hóa lại. Khi làm việc với biểu thức chính quy hãy chắc chắn sử dụng công cụ sửa đổi u.

Trong văn bản Trình soạn thảo sổ tay++, nếu mã hóa khác với UTF-8, hãy sử dụng mục menu “Chuyển sang UTF-8 không có BOM” để thay đổi mã hóa và lưu ở dạng mã hóa UTF-8.

Không có cách thay thế

Trong bối cảnh toàn cầu hóa, khi ranh giới chính trị và ngôn ngữ bị xóa bỏ, các bộ ký tự mang tính địa phương trở nên ít được sử dụng. Unicode là bộ ký tự duy nhất hỗ trợ tất cả các ngôn ngữ. Và UTF-8 là một ví dụ về việc triển khai đúng Unicode, trong đó:

  • hỗ trợ nhiều loại công cụ, bao gồm khả năng tương thích ASCII;
  • có khả năng chống tham nhũng dữ liệu;
  • đơn giản và hiệu quả trong chế biến;
  • là nền tảng độc lập.

Với sự ra đời của UTF-8, các cuộc thảo luận về hình thức mã hóa hoặc bộ ký tự nào tốt hơn đã trở nên vô nghĩa.