Tôi đã nghe những ý kiến trái ngược từ mọi người - theo trang Wikipedia UTF-8 .
Họ là những điều tương tự, phải không? Ai đó có thể làm rõ?
Tôi đã nghe những ý kiến trái ngược từ mọi người - theo trang Wikipedia UTF-8 .
Họ là những điều tương tự, phải không? Ai đó có thể làm rõ?
Câu trả lời:
Để mở rộng câu trả lời mà người khác đã đưa ra:
Chúng tôi đã có rất nhiều ngôn ngữ với nhiều ký tự mà máy tính sẽ hiển thị lý tưởng. Unicode gán cho mỗi ký tự một số duy nhất hoặc điểm mã.
Máy tính xử lý các số như byte ... bỏ qua một chút lịch sử ở đây và bỏ qua các vấn đề giải quyết bộ nhớ, máy tính 8 bit sẽ coi một byte 8 bit là đơn vị số lớn nhất dễ dàng biểu thị trên phần cứng, máy tính 16 bit sẽ mở rộng đến hai byte, v.v.
Các mã hóa ký tự cũ như ASCII có từ thời đại 8 bit (trước) và cố gắng nhồi nhét ngôn ngữ thống trị trong điện toán vào thời điểm đó, tức là tiếng Anh, thành các số từ 0 đến 127 (7 bit). Với 26 chữ cái trong bảng chữ cái, cả ở dạng viết hoa và không viết hoa, số và dấu chấm câu, hoạt động khá tốt. ASCII đã được mở rộng thêm 8 bit cho các ngôn ngữ khác, không phải tiếng Anh, nhưng 128 số / điểm mã bổ sung có sẵn của bản mở rộng này sẽ được ánh xạ tới các ký tự khác nhau tùy thuộc vào ngôn ngữ được hiển thị. Các tiêu chuẩn ISO-8859 là các hình thức phổ biến nhất của ánh xạ này; ISO-8859-1 và ISO-8859-15 (còn được gọi là ISO-Latin-1, latin1, và vâng, có hai phiên bản khác nhau của tiêu chuẩn ISO 8859).
Nhưng điều đó là không đủ khi bạn muốn thể hiện các ký tự từ nhiều ngôn ngữ, vì vậy việc nhồi nhét tất cả các ký tự có sẵn vào một byte sẽ không hoạt động.
Về cơ bản có hai loại mã hóa khác nhau: một loại mở rộng phạm vi giá trị bằng cách thêm nhiều bit. Ví dụ về các bảng mã này sẽ là UCS2 (2 byte = 16 bit) và UCS4 (4 byte = 32 bit). Họ bị vấn đề tương tự như các tiêu chuẩn ASCII và ISO-8859, vì phạm vi giá trị của chúng vẫn còn hạn chế, ngay cả khi giới hạn cao hơn rất nhiều.
Loại mã hóa khác sử dụng số byte thay đổi trên mỗi ký tự và mã hóa được biết đến nhiều nhất cho điều này là mã hóa UTF. Tất cả các mã hóa UTF hoạt động theo cách gần giống nhau: bạn chọn kích thước đơn vị, đối với UTF-8 là 8 bit, đối với UTF-16 là 16 bit và đối với UTF-32 là 32 bit. Sau đó, tiêu chuẩn định nghĩa một vài trong số các bit này là cờ: nếu chúng được đặt, thì đơn vị tiếp theo trong chuỗi đơn vị sẽ được coi là một phần của cùng một ký tự. Nếu chúng không được đặt, đơn vị này thể hiện đầy đủ một ký tự. Do đó, các ký tự (tiếng Anh) phổ biến nhất chỉ chiếm một byte trong UTF-8 (hai trong UTF-16, 4 trong UTF-32), nhưng các ký tự ngôn ngữ khác có thể chiếm sáu byte trở lên.
Mã hóa nhiều byte (tôi nên nói là đa đơn vị sau khi giải thích ở trên) có ưu điểm là chúng tương đối hiệu quả về mặt không gian, nhưng nhược điểm của các hoạt động như tìm chuỗi, so sánh, v.v ... đều phải giải mã các ký tự thành mã unicode điểm trước khi các hoạt động như vậy có thể được thực hiện (mặc dù có một số phím tắt).
Cả tiêu chuẩn UCS và tiêu chuẩn UTF đều mã hóa các điểm mã như được định nghĩa trong Unicode. Về lý thuyết, các mã hóa đó có thể được sử dụng để mã hóa bất kỳ số nào (trong phạm vi hỗ trợ mã hóa) - nhưng tất nhiên các mã hóa này được thực hiện để mã hóa các điểm mã Unicode. Và đó là mối quan hệ của bạn giữa họ.
Windows xử lý các chuỗi được gọi là "Unicode" dưới dạng chuỗi UTF-16, trong khi hầu hết các UNIX mặc định là UTF-8 ngày nay. Các giao thức truyền thông như HTTP có xu hướng hoạt động tốt nhất với UTF-8, vì kích thước đơn vị trong UTF-8 giống như trong ASCII và hầu hết các giao thức như vậy được thiết kế trong thời đại ASCII. Mặt khác, UTF-16 cho hiệu suất xử lý / không gian trung bình tốt nhất khi đại diện cho tất cả các ngôn ngữ sống.
Tiêu chuẩn Unicode xác định ít điểm mã hơn có thể được biểu diễn trong 32 bit. Do đó, cho tất cả các mục đích thực tế, UTF-32 và UCS4 đã trở thành cùng một mã hóa, vì bạn không cần phải xử lý các ký tự nhiều đơn vị trong UTF-32.
Hy vọng rằng điền vào một số chi tiết.
0x04000000
đến 0x7FFFFFFF
hoặc trong nhị phân 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
- và đó thực sự là 6 byte. Tuy nhiên, 6 byte là tối đa , và không phải như bài viết tuyên bố một cách khó hiểu "sáu byte trở lên ".
Hãy để tôi sử dụng một ví dụ để minh họa chủ đề này:
A chinese character: 汉
it's unicode value: U+6C49
convert 6C49 to binary: 01101100 01001001
Không có gì kỳ diệu cho đến nay, nó rất đơn giản. Bây giờ, giả sử chúng ta quyết định lưu trữ ký tự này trên ổ cứng. Để làm điều đó, chúng ta cần lưu trữ ký tự ở định dạng nhị phân. Chúng tôi chỉ đơn giản có thể lưu trữ nó là '01101100 01001001'. Làm xong!
Nhưng hãy đợi một phút, là '01101100 01001001' một ký tự hay hai ký tự? Bạn biết đây là một nhân vật bởi vì tôi đã nói với bạn, nhưng khi một máy tính đọc nó, nó không có ý kiến gì. Vì vậy, chúng ta cần một số loại "mã hóa" để báo cho máy tính coi nó là một.
Đây là nơi quy tắc của 'UTF-8' xuất hiện: http://www.fileformat.info/info/unicode/utf8.htm
Binary format of bytes in sequence
1st Byte 2nd Byte 3rd Byte 4th Byte Number of Free Bits Maximum Expressible Unicode Value
0xxxxxxx 7 007F hex (127)
110xxxxx 10xxxxxx (5+6)=11 07FF hex (2047)
1110xxxx 10xxxxxx 10xxxxxx (4+6+6)=16 FFFF hex (65535)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (3+6+6+6)=21 10FFFF hex (1,114,111)
Theo bảng trên, nếu chúng ta muốn lưu trữ ký tự này bằng định dạng 'UTF-8', chúng ta cần thêm tiền tố vào ký tự của mình bằng một số 'tiêu đề'. Ký tự tiếng Trung của chúng tôi dài 16 bit (tự đếm giá trị nhị phân), vì vậy chúng tôi sẽ sử dụng định dạng trên hàng 3 vì nó cung cấp đủ không gian:
Header Place holder Fill in our Binary Result
1110 xxxx 0110 11100110
10 xxxxxx 110001 10110001
10 xxxxxx 001001 10001001
Viết ra kết quả trong một dòng:
11100110 10110001 10001001
Đây là giá trị UTF-8 (nhị phân) của ký tự Trung Quốc! (tự xác nhận: http://www.fileformat.info/info/unicode/char/6c49/index.htm )
A chinese character: 汉
it's unicode value: U+6C49
convert 6C49 to binary: 01101100 01001001
embed 6C49 as UTF-8: 11100110 10110001 10001001
PS Nếu bạn muốn tìm hiểu chủ đề này trong python, bấm vào đây
0
thì ký tự được biểu thị bằng 1 cắn (hiện tại), nếu byte bắt đầu bằng 110
thì ký tự được biểu thị bằng 2 byte (hiện tại và tiếp theo ( các bit còn lại sau 10
)), nếu byte bắt đầu bằng 1110
thì ký tự được biểu thị bằng 3 byte, hiện tại và 2 byte tiếp theo (các bit còn lại sau 10
).
"Unicode" không may được sử dụng theo nhiều cách khác nhau, tùy thuộc vào ngữ cảnh. Cách sử dụng đúng nhất của nó (IMO) là một bộ ký tự được mã hóa - tức là một bộ ký tự và ánh xạ giữa các ký tự và các điểm mã nguyên biểu thị chúng.
UTF-8 là một mã hóa ký tự - một cách chuyển đổi từ chuỗi byte sang chuỗi ký tự và ngược lại. Nó bao gồm toàn bộ bộ ký tự Unicode. ASCII được mã hóa dưới dạng một byte cho mỗi ký tự và các ký tự khác lấy nhiều byte hơn tùy thuộc vào điểm mã chính xác của chúng (tối đa 4 byte cho tất cả các điểm mã được xác định hiện tại, tức là lên đến U-0010FFFF và thực sự 4 byte có thể đối phó với tối đa U-001FFFFF).
Khi "Unicode" được sử dụng làm tên của mã hóa ký tự (ví dụ như thuộc tính .NET Encoding.Unicode ), nó thường có nghĩa là UTF-16 , mã hóa hầu hết các ký tự phổ biến thành hai byte. Một số nền tảng (đặc biệt là .NET và Java) sử dụng UTF-16 làm mã hóa ký tự "gốc" của chúng. Điều này dẫn đến các vấn đề về lông nếu bạn cần lo lắng về các ký tự không thể được mã hóa trong một giá trị UTF-16 (chúng được mã hóa thành "cặp thay thế") - nhưng hầu hết các nhà phát triển không bao giờ lo lắng về điều này, IME.
Một số tài liệu tham khảo về Unicode:
Chúng không giống nhau - UTF-8 là một cách mã hóa Unicode cụ thể.
Có rất nhiều mã hóa khác nhau mà bạn có thể chọn tùy thuộc vào ứng dụng của bạn và dữ liệu bạn định sử dụng. Phổ biến nhất là UTF-8, UTF-16 và UTF-32 s theo như tôi biết.
Unicode chỉ xác định các điểm mã , nghĩa là một số đại diện cho một ký tự. Cách bạn lưu trữ các điểm mã này trong bộ nhớ tùy thuộc vào mã hóa mà bạn đang sử dụng. UTF-8 là một cách mã hóa các ký tự Unicode, trong số nhiều cách khác.
Unicode là một tiêu chuẩn xác định, cùng với ISO / IEC 10646, Bộ ký tự phổ quát (UCS) , là siêu ký tự của tất cả các ký tự hiện có được yêu cầu để thể hiện thực tế tất cả các ngôn ngữ đã biết.
Unicode gán Tên và Số ( Mã ký tự hoặc Điểm mã ) cho mỗi ký tự trong tiết mục của nó.
Mã hóa UTF-8 , là một cách để thể hiện các ký tự này bằng kỹ thuật số trong bộ nhớ máy tính. UTF-8 ánh xạ mỗi điểm mã thành một chuỗi các octet (byte 8 bit)
Ví dụ:
Ký tự UCS = Ký tự chữ Hán
Điểm mã UCS = U + 24B62
Mã hóa UTF-8 = F0 A4 AD A2 (hex) = 11110000 10100100 10101101 10100010 (bin)
http://www.wikiwand.com/en/UTF-8#/Description
Có một cái nhìn vào hàng đầu tiên.
Unicode chỉ là một tiêu chuẩn xác định một bộ ký tự ( UCS ) và mã hóa ( UTF ) để mã hóa bộ ký tự này. Nhưng nói chung, Unicode được giới thiệu đến bộ ký tự và không phải là tiêu chuẩn.
Đọc Tối thiểu tuyệt đối Mỗi nhà phát triển phần mềm Tuyệt đối, Phải tích cực phải biết về Unicode và Bộ ký tự (Không có lý do!) Và Unicode trong 5 phút .
Các câu trả lời hiện có đã giải thích rất nhiều chi tiết, nhưng đây là một câu trả lời rất ngắn với lời giải thích và ví dụ trực tiếp nhất.
Unicode là tiêu chuẩn ánh xạ các ký tự thành các điểm mã.
Mỗi ký tự có một mật mã duy nhất (số nhận dạng), là một số như 9731.
UTF-8 là một sự mã hóa của codepoints.
Để lưu trữ tất cả các ký tự trên đĩa (trong một tệp), UTF-8 chia các ký tự thành tối đa 4 octet (chuỗi 8 bit) - byte. UTF-8 là một trong một số mã hóa (phương pháp biểu diễn dữ liệu). Ví dụ: trong Unicode, mã số (thập phân) 9731 đại diện cho người tuyết ( ☃
), bao gồm 3 byte trong UTF-8:E2 98 83
Đây là một danh sách được sắp xếp với một số ví dụ ngẫu nhiên .
Có rất nhiều nhân vật trên khắp thế giới, như "$, &, h, a, t,?,, 1, =, + ...".
Sau đó, có một tổ chức dành riêng cho những nhân vật này,
Họ đã tạo ra một tiêu chuẩn gọi là "Unicode".
Tiêu chuẩn như sau:
PS: Tất nhiên có một tổ chức khác gọi là ISO duy trì một tiêu chuẩn khác - "ISO 10646" gần giống nhau.
Như trên, U + 0024 chỉ là một vị trí, vì vậy chúng tôi không thể lưu "U + 0024" trong máy tính cho ký tự "$".
Phải có một phương pháp mã hóa.
Sau đó, đến các phương thức mã hóa, chẳng hạn như UTF-8, UTF-16, UTF-32, UCS-2 ....
Theo UTF-8, điểm mã "U + 0024" được mã hóa thành 00100100.
00100100 là giá trị chúng tôi lưu trong máy tính với giá "$".
Tôi đã kiểm tra các liên kết trong câu trả lời của Gumbo và tôi cũng muốn dán một phần của những thứ đó vào đây để tồn tại trên Stack Overflow.
"... Một số người theo quan niệm sai lầm rằng Unicode chỉ đơn giản là mã 16 bit trong đó mỗi ký tự lấy 16 bit và do đó có 65.536 ký tự có thể. Thực tế, đây không phải là chính xác. Đây là huyền thoại phổ biến nhất về Unicode , vì vậy nếu bạn nghĩ vậy, đừng cảm thấy tồi tệ.
Trên thực tế, Unicode có cách nghĩ khác về các ký tự và bạn phải hiểu cách suy nghĩ của Unicode về mọi thứ hoặc không có gì có ý nghĩa.
Cho đến bây giờ, chúng tôi đã giả sử rằng một chữ cái ánh xạ tới một số bit mà bạn có thể lưu trữ trên đĩa hoặc trong bộ nhớ:
A -> 0100 0001
Trong Unicode, một chữ cái ánh xạ tới một thứ gọi là điểm mã vẫn chỉ là một khái niệm lý thuyết. Làm thế nào điểm mã được thể hiện trong bộ nhớ hoặc trên đĩa là cả một câu chuyện khác ... "
"... Mỗi chữ cái trong mỗi bảng chữ cái được gán một số ma thuật bởi tập đoàn Unicode được viết như sau: U + 0639. Số ma thuật này được gọi là điểm mã. U + có nghĩa là" Unicode "và các số là thập lục phân. U + 0639 là chữ cái Ả Rập Ain. Chữ cái tiếng Anh A sẽ là U + 0041 .... "
"... OK, vì vậy giả sử chúng ta có một chuỗi:
xin chào
trong Unicode, tương ứng với năm điểm mã sau:
U + 0048 U + 0065 U + 006C U + 006C U + 006F.
Chỉ là một loạt các điểm mã. Những con số, thực sự. Chúng tôi chưa nói gì về cách lưu trữ thứ này trong bộ nhớ hoặc thể hiện nó trong thông điệp email ... "
"... Đó là nơi mã hóa đi vào.
Ý tưởng sớm nhất về mã hóa Unicode, dẫn đến huyền thoại về hai byte, là, chúng ta hãy lưu trữ các số đó trong hai byte mỗi byte. Vì vậy, Xin chào trở thành
00 48 00 65 00 6C 00 6C 00 6F
Đúng? Không quá nhanh! Cũng không thể:
48 00 65 00 6C 00 6C 00 6F 00? ... "
UTF-8 là một sơ đồ mã hóa có thể có cho Unicode văn bản .
Unicode là một tiêu chuẩn có phạm vi rộng, xác định hơn 130.000 ký tự và phân bổ cho mỗi mã số (một điểm mã). Nó cũng xác định các quy tắc về cách sắp xếp văn bản này, bình thường hóa nó, thay đổi trường hợp của nó và hơn thế nữa. Một ký tự trong Unicode được biểu thị bằng một điểm mã từ 0 đến 0x10FFFF, mặc dù một số điểm mã được dành riêng và không thể được sử dụng cho các ký tự.
Có nhiều hơn một cách mà một chuỗi các điểm mã Unicode có thể được mã hóa thành một luồng nhị phân. Chúng được gọi là "mã hóa". Mã hóa đơn giản nhất là UTF-32 , chỉ đơn giản lưu trữ mỗi điểm mã dưới dạng số nguyên 32 bit, mỗi mã có chiều rộng 4 byte.
UTF-8 là một mã hóa khác, và đang trở thành tiêu chuẩn thực tế, do một số lợi thế so với UTF-32 và các loại khác. UTF-8 mã hóa thành một chuỗi các giá trị byte đơn. Mỗi điểm mã có thể sử dụng một số lượng khác nhau của các giá trị byte này. Các điểm mã trong phạm vi ASCII được mã hóa trần, để tương thích với ASCII. Các điểm mã nằm ngoài phạm vi này sử dụng số byte thay đổi, 2, 3 hoặc 4, tùy thuộc vào phạm vi chúng nằm trong phạm vi nào.
UTF-8 đã được thiết kế với các đặc tính này:
Các ký tự ASCII được mã hóa chính xác như trong ASCII, sao cho chuỗi ASCII cũng là chuỗi UTF-8 hợp lệ.
Sắp xếp nhị phân: Sắp xếp các chuỗi UTF-8 bằng cách sử dụng sắp xếp nhị phân ngây thơ sẽ vẫn dẫn đến tất cả các điểm mã được sắp xếp theo thứ tự số.
Các ký tự yêu cầu nhiều byte không chứa bất kỳ giá trị byte nào trong phạm vi ASCII, đảm bảo một phần của chúng không thể bị nhầm với các ký tự ASCII. Đây cũng là một tính năng bảo mật.
UTF-8 có thể được xác nhận dễ dàng và được phân biệt với các mã hóa ký tự khác bởi một trình xác nhận. Văn bản trong các bảng mã 8 bit hoặc nhiều byte khác sẽ hiếm khi xác nhận là UTF-8.
Truy cập ngẫu nhiên: Tại bất kỳ điểm nào trong chuỗi UTF-8, có thể cho biết byte ở vị trí đó có phải là byte đầu tiên của ký tự hay không và để tìm bắt đầu của ký tự tiếp theo hoặc hiện tại, mà không cần phải quét về phía trước hoặc ngược hơn một vài byte hoặc đọc bất cứ thứ gì khi bắt đầu luồng.
Họ là những điều tương tự, phải không?
Không, họ không.
Tôi nghĩ rằng câu đầu tiên của trang Wikipedia mà bạn tham chiếu đưa ra một bản tóm tắt hay, ngắn gọn:
UTF-8 là mã hóa ký tự có chiều rộng thay đổi có khả năng mã hóa tất cả 1.112.064 điểm mã hợp lệ trong Unicode bằng cách sử dụng một đến bốn byte 8 bit.
Để giải thích:
Unicode là một tiêu chuẩn, định nghĩa một bản đồ từ các ký tự đến các số, được gọi là các điểm mã , (như trong ví dụ dưới đây). Đối với bản đồ đầy đủ, bạn có thể có một cái nhìn ở đây .
! -> U+0021 (21),
" -> U+0022 (22),
\# -> U+0023 (23)
UTF-8 là một trong những cách để mã hóa các điểm mã này dưới dạng máy tính có thể hiểu, còn gọi là bit . Nói cách khác, đó là một cách / thuật toán để chuyển đổi từng điểm mã đó thành một chuỗi bit hoặc chuyển đổi một chuỗi bit thành các điểm mã tương đương. Lưu ý rằng có rất nhiều bảng mã thay thế cho Unicode.
Joel đưa ra một lời giải thích thực sự tốt đẹp và một cái nhìn tổng quan về lịch sử ở đây .
Nếu tôi có thể tóm tắt những gì tôi thu thập được từ chủ đề này:
Unicode 'dịch các ký tự thành số thứ tự (ở dạng thập phân) .
à = 224
UTF-8 là một mã hóa 'dịch' các số này thành các biểu diễn nhị phân .
224 = 11000011 10100000
Lưu ý rằng chúng ta đang nói về biểu diễn nhị phân của 224, không phải dạng nhị phân của nó, là 0b11100000.
Bài viết này giải thích tất cả các chi tiết http://kunststube.net/encoding/
VIẾT ĐỂ BUFFER
nếu bạn ghi vào bộ đệm 4 byte, ký hiệu あ
có mã hóa UTF8, tệp nhị phân của bạn sẽ trông như thế này:
00000000 11100011 10000001 10000010
nếu bạn ghi vào bộ đệm 4 byte, ký hiệu あ
có mã hóa UTF16, tệp nhị phân của bạn sẽ trông như thế này:
00000000 00000000 00110000 01000010
Như bạn có thể thấy, tùy thuộc vào ngôn ngữ bạn sẽ sử dụng trong nội dung của mình, điều này sẽ ảnh hưởng đến bộ nhớ của bạn.
ví dụ: Đối với biểu tượng cụ thể này: あ
mã hóa UTF16 hiệu quả hơn vì chúng tôi có 2 byte dự phòng để sử dụng cho biểu tượng tiếp theo. Nhưng điều đó không có nghĩa là bạn phải sử dụng bảng chữ cái UTF16 cho Nhật Bản.
ĐỌC TỪ BUFFER
Bây giờ nếu bạn muốn đọc các byte ở trên, bạn phải biết nó được viết mã hóa và giải mã lại chính xác.
ví dụ: Nếu bạn giải mã điều này:
00000000 11100011 10000001 10000010
thành mã hóa UTF16, bạn sẽ 臣
khôngあ
Lưu ý: Mã hóa và Unicode là hai thứ khác nhau. Unicode là bảng (bảng) lớn với mỗi ký hiệu được ánh xạ tới một điểm mã duy nhất. ví dụ: あ
ký hiệu (chữ cái) có (điểm mã) : 30 42 (hex). Mặt khác, mã hóa là một thuật toán chuyển đổi các ký hiệu thành cách thích hợp hơn, khi lưu trữ vào phần cứng.
30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.
30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.