"Mã hóa độ rộng thay đổi" UTF-8 hoạt động như thế nào?


110

Tiêu chuẩn unicode có đủ điểm mã mà bạn cần 4 byte để lưu trữ tất cả. Đó là những gì mã hóa UTF-32 làm. Tuy nhiên, mã hóa UTF-8 bằng cách nào đó ép chúng vào những không gian nhỏ hơn nhiều bằng cách sử dụng một thứ gọi là "mã hóa chiều rộng thay đổi".

Trên thực tế, nó quản lý để đại diện cho 127 ký tự đầu tiên của US-ASCII chỉ trong một byte trông giống hệt như ASCII thực, vì vậy bạn có thể diễn giải nhiều văn bản ascii như thể nó là UTF-8 mà không cần làm gì với nó. Trò hay. Vì vậy, làm thế nào nó hoạt động?

Tôi sẽ hỏi và trả lời câu hỏi của chính mình ở đây bởi vì tôi chỉ đọc một chút để tìm ra nó và tôi nghĩ rằng nó có thể cứu ai đó một thời gian. Thêm vào đó, có thể ai đó có thể sửa cho tôi nếu tôi có một số sai.


8
Unicode thẳng không yêu cầu 32 bit để mã hóa tất cả các điểm mã của nó. Họ đã từng tuyên bố rằng có nhiều điểm mã, nhưng sau khi UTF-8 cất cánh, họ đã cố ý giới hạn bản thân ở mức 21 bit, để UTF-8 sẽ không bao giờ vượt quá 4 byte cho mỗi ký tự. Unicode hiện chỉ yêu cầu 17 bit để chứa tất cả các điểm mã có thể. Nếu không có giới hạn này, UTF-8 có thể có tới 6 byte cho mỗi ký tự.
Warren Young

@Warren: chủ yếu là chính xác, nhưng Unicode là mã 21 bit (U + 0000 đến U + 10FFFF).
Jonathan Leffler

2
@Warren: UTF-8 giới hạn 4 byte có thể đã hỗ trợ tối đa U + 1FFFFF. Hạn chế đối với U + 10FFFF được thực hiện vì lợi ích của UTF-16.
dan04

@ dan04 Chúng tôi có bất kỳ giải thích dễ dàng nào về cách nó bị hạn chế đối với U + 10FFFF bởi UTF-16 không? Sẽ rất vui nếu biết thêm về điều này.
A-letubby 29/02/16

@ A-letubby: Vì mã "đại diện" UTF-16 được phân bổ sao cho có 1024 ký tự thay thế chính và 1024 ký tự thay thế đường mòn (và chúng chỉ có thể được sử dụng theo cặp), để tạo thêm 2 ^ 20 (khoảng một triệu) ký tự có sẵn ngoài BMP. Đã thêm vào 2 ^ 16 ký tự có sẵn trong BMP, điều này làm cho 0x110000 ký tự khả thi.
dan04 29/02/16

Câu trả lời:


129

Mỗi byte bắt đầu bằng một vài bit cho bạn biết đó là điểm mã byte đơn, điểm mã nhiều byte hay phần tiếp theo của điểm mã nhiều byte. Như thế này:

0xxx xxxx    A single-byte US-ASCII code (from the first 127 characters)

Mỗi điểm mã nhiều byte bắt đầu bằng một vài bit về cơ bản nói rằng "này, bạn cũng cần đọc byte tiếp theo (hoặc hai hoặc ba) để tìm ra tôi là gì." Họ đang:

110x xxxx    One more byte follows
1110 xxxx    Two more bytes follow
1111 0xxx    Three more bytes follow

Cuối cùng, các byte theo sau các mã bắt đầu đó đều trông giống như sau:

10xx xxxx    A continuation of one of the multi-byte characters

Vì bạn có thể biết bạn đang xem loại byte nào từ vài bit đầu tiên, nên ngay cả khi có thứ gì đó bị xáo trộn ở đâu đó, bạn không bị mất toàn bộ chuỗi.


14
Câu chuyện còn nhiều điều hơn thế - bởi vì mã hóa phải là mã hóa ngắn nhất có thể cho ký tự, điều này kết thúc có nghĩa là các byte 0xC0 và 0xC1 không thể xuất hiện trong UTF-8 chẳng hạn; và trên thực tế, 0xF5..0xFF cũng không. Xem Câu hỏi thường gặp về UTF-8 tại unicode.org/faq/utf_bom.html hoặc unicode.org/versions/Unicode5.2.0/ch03.pdf
Jonathan Leffler 21/10/09

2
Tại sao nó không thể chỉ sử dụng một ký tự để nói next char is continuation? Nếu chúng ta có ký tự 3 byte thì nó sẽ giống như : 1xxxxxxx 1xxxxxxx 0xxxxxxx, vì vậy sẽ ít không gian hơn sẽ bị lãng phí.

9
@Soaku nó làm cho UTF-8 được gọi là mã "tự đồng bộ hóa". Điều này có nghĩa là nếu do lỗi các phần của trình tự bị thiếu, có thể phát hiện ra điều đó và loại bỏ bất kỳ phần nào bị cắt xén. Nếu bạn đọc một byte bắt đầu bằng 10xx và không có byte "bắt đầu" trước đó, bạn có thể loại bỏ nó vì nó vô nghĩa. Nếu bạn có một hệ thống như bạn đã mô tả và một trong những byte đầu tiên bị mất, bạn có thể nhận được một ký tự hợp lệ khác mà không có dấu hiệu của bất kỳ loại lỗi nào. Nó cũng sẽ giúp bạn dễ dàng tìm ký tự hợp lệ tiếp theo, cũng như sửa các byte "tiếp theo" bị thiếu.
htmlcoderexe

9

RFC3629 - UTF-8, định dạng chuyển đổi của ISO 10646 là cơ quan có thẩm quyền cuối cùng ở đây và có tất cả các giải thích.

Nói tóm lại, một số bit trong mỗi byte của chuỗi 1 đến 4 byte được mã hóa UTF-8 đại diện cho một ký tự duy nhất được sử dụng để cho biết đó là byte cuối, byte đầu và nếu có, bao nhiêu byte theo sau. Các bit còn lại chứa trọng tải.


1
Ummmm, ngớ ngẩn tôi, tôi nghĩ rằng các tiêu chuẩn Unicode là thẩm quyền cuối cùng về UTF-8
John Machin

6
Chuẩn Unicode xác định chính Unicode. Nó không xác định các phương pháp khác nhau, ngày nay và tương lai, có thể được sử dụng để mã hóa văn bản unicode cho nhiều mục đích khác nhau (chẳng hạn như lưu trữ và vận chuyển). UTF-8 là một trong những phương pháp đó và tài liệu tham khảo ở trên là tài liệu định nghĩa nó.
azheglov

1
RFC3629, trang 3, phần 3. cho biết "UTF-8 được xác định bởi Tiêu chuẩn Unicode".
John Machin

Việc theo dõi các liên kết trên unicode.org đã đưa tôi đến phần 3.9 của Tiêu chuẩn Unicode và định nghĩa cụ thể là D92 (và cũng là D86 tiếp tuyến). Tôi không biết liên kết này sẽ hữu ích ở mức độ nào khi các phiên bản mới được phát hành nhưng tôi có thể tưởng tượng rằng họ muốn giữ cho phần và định nghĩa nhận dạng ổn định giữa các phiên bản.
tripleee

4

UTF-8 là một hệ thống khác để lưu trữ chuỗi các điểm mã Unicode, những số U + kỳ diệu đó, trong bộ nhớ bằng cách sử dụng 8 byte bit. Trong UTF-8, mọi điểm mã từ 0-127 được lưu trữ trong một byte duy nhất. Trên thực tế, chỉ có các điểm mã 128 trở lên được lưu trữ bằng 2, 3, tối đa 6 byte.

Trích từ Điều tối thiểu tuyệt đối Mọi nhà phát triển phần mềm Tuyệt đối, Tích cực phải biết về Unicode và Bộ ký tự (Không có lý do!)


Đó là một bài báo hay, nhưng có vẻ như Joel đã sai về độ dài tối đa của chuỗi; trang Wikipedia chỉ hiển thị 1..4 byte cho mỗi ký tự.
thư giãn

4
Như tôi đã nói ở trên, khi UTF-8 lần đầu tiên được tạo, Unicode tuyên bố lên đến 32-bit cho các điểm mã, không phải vì họ thực sự cần nó, chỉ vì 32-bit là một giá trị thuận tiện và chúng đã vượt qua giới hạn ký tự 16 bit trước đó. Sau khi UTF-8 trở nên phổ biến, họ đã chọn giới hạn vĩnh viễn số điểm mã tối đa là 2 ^ 21, đó là giá trị lớn nhất mà bạn có thể mã hóa bằng 4 byte của lược đồ UTF-8. Vẫn còn ít hơn 2 ^ 17 ký tự trong Unicode, vì vậy chúng tôi có thể tăng gấp bốn lần số ký tự trong Unicode với lược đồ mới này.
Warren Young

Ok nhưng không phải lời giải thích của OP.
Nishant

2
Đây không phải là câu trả lời cho câu hỏi.
Koray Tugay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.