Sự khác biệt giữa mã hóa và bảng mã là gì?


151

Tôi bối rối về mã hóa văn bản và bảng mã. Vì nhiều lý do, tôi phải học những thứ không phải là Unicode, không phải UTF8 trong công việc sắp tới của tôi.

Tôi tìm thấy từ "bộ ký tự" trong các tiêu đề email như trong "ISO-2022-JP", nhưng không có mã hóa như vậy trong trình soạn thảo văn bản. (Tôi nhìn xung quanh các trình soạn thảo văn bản khác nhau.)

Sự khác biệt giữa mã hóa văn bản và bảng mã là gì? Tôi sẽ đánh giá cao nếu bạn có thể chỉ cho tôi một số ví dụ sử dụng.


Câu trả lời:


144

Về cơ bản:

  1. bộ ký tự là tập hợp các ký tự bạn có thể sử dụng
  2. mã hóa là cách các ký tự này được lưu trữ vào bộ nhớ

42
Đúng, nhưng trong thực tế sử dụng "bộ ký tự" thường đề cập đến cả tiết mục nhân vật và sơ đồ mã hóa.
Alan Moore

@AlanMoore Thật vậy, khá giống cách mọi người nói "số thập phân" để chỉ bất kỳ số nào có "dấu tách thập phân". Điều đó không thực sự chính xác, nhưng vâng, bạn nên biết rằng một số người sử dụng nó như thế.
bvdb

2
Điều đó không chính xác. Ví dụ, Unicode đề cập đến bộ ký tự, nhưng có nhiều mã hóa có thể có (UTF-8, UTF-16, UTF-32).
rghome

84

Mỗi mã hóa có một bộ ký tự cụ thể được liên kết với nó, nhưng có thể có nhiều hơn một mã hóa cho một bộ ký tự nhất định. Một bộ ký tự đơn giản là những gì nó nghe như, một bộ ký tự. Có một số lượng lớn các bảng mã, bao gồm nhiều bảng được dành cho các tập lệnh hoặc ngôn ngữ cụ thể.

Tuy nhiên, chúng tôi đang trong quá trình chuyển đổi sang Unicode, bao gồm một bộ ký tự có khả năng đại diện cho hầu hết các tập lệnh của thế giới. Tuy nhiên, có nhiều bảng mã cho Unicode. Mã hóa là một cách ánh xạ một chuỗi ký tự thành một chuỗi byte. Ví dụ về mã hóa Unicode bao gồm UTF-8 , UTF-16 BEUTF-16 LE . Mỗi trong số này có lợi thế cho các ứng dụng cụ thể hoặc kiến ​​trúc máy.


20
Lưu ý rằng javadoc sử dụng sai "bộ ký tự" thay vì "mã hóa", ví dụ như trong InputStreamReader , chúng tôi đọc "Một InputStreamReader là một cầu nối từ các luồng byte đến các luồng ký tự: Nó đọc các byte và giải mã chúng thành các ký tự được sử dụng. việc sử dụng có thể được chỉ định theo tên hoặc có thể được cung cấp rõ ràng hoặc bộ ký tự mặc định của nền tảng có thể được chấp nhận. " . Tuy nhiên, ý nghĩa của chúng là "mã hóa".
David Tonhofer

4
Cảm ơn bạn đã giải thích. Unicode là một bộ ký tự và UTF-8 là một cách mã hóa của UnicodeUTF-16 là một cách mã hóa khác của Unicode .
HongchaoZhang 17/8/2016

47

Ngoài các câu trả lời khác, tôi nghĩ rằng bài viết này rất hay đọc http://www.joelonsoftware.com/articles/Unicode.html

Bài viết có tiê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ề bộ ký tự và ký tự (không có lý do!) " Được viết bởi Joel Spolsky . Bài luận đã hơn 10 năm nhưng (thật không may) nội dung vẫn còn hiệu lực ...


2
Cảm ơn rất nhiều vì đã giới thiệu bài viết. Nó một trong những tốt.
TK.

9
Câu trả lời này có thể được cải thiện bằng cách đưa ra một lời giải thích ngắn về lý do tại sao tôi nên đọc bài viết của Joel.
james.garriss

@mattanja Liên kết bạn cung cấp là thực sự tuyệt vời. Cám ơn vì đã chia sẻ. Bỏ phiếu lên.
hagrawal

1
Tôi cũng muốn đặt bài viết tuyệt vời này là phần phụ lục của Joel Spolsky; kunststube.net/encoding
mkb

Tôi đã không hiểu bài viết của Joel khi đọc lần đầu tiên. Thay vào đó, tôi thấy powerpoint này rõ ràng và cụ thể hơn nhiều: unicode.org/notes/tn23/Muller-Slides+Narr.pdf
johnsimer

27

Một mã hóa ký tự bao gồm:

  1. Tập hợp các ký tự được hỗ trợ
  2. Ánh xạ giữa các ký tự và số nguyên ("điểm mã")
  3. Cách các điểm mã được mã hóa thành một chuỗi "đơn vị mã" (ví dụ: đơn vị 16 bit cho UTF-16)
  4. Làm thế nào các đơn vị mã được mã hóa thành byte (ví dụ: big endian hoặc little endian)

Bước # 1 tự nó là một "tiết mục nhân vật" hoặc "bộ ký tự" trừu tượng và # 1 + # 2 = một "bộ ký tự được mã hóa".

Nhưng trở lại trước khi Unicode trở nên phổ biến và mọi người (trừ người Đông Á) đang sử dụng mã hóa một byte, các bước # 3 và # 4 là tầm thường (code point = code unit = byte). Do đó, các giao thức cũ không phân biệt rõ ràng giữa "mã hóa ký tự" và "bộ ký tự được mã hóa". Các giao thức cũ sử dụng charsetkhi chúng thực sự có nghĩa là mã hóa.


đó có phải là lý do tại sao chúng ta có thể đọc charset = 'utf-8' trong thẻ META html không? bởi vì nó đã được định nghĩa từ lâu
Eildosa

26

Ném thêm ánh sáng cho những người đến thăm từ đó, hy vọng nó sẽ hữu ích.


Bộ ký tự

Có những nhân vật trong mỗi ngôn ngữ và bộ sưu tập của những nhân vật đó tạo thành bộ ký tự của bộ bộ phận ngôn ngữ đó. Khi một ký tự được mã hóa thì nó được gán một mã định danh duy nhất hoặc một số được gọi là điểm mã. Trong máy tính, các điểm mã này sẽ được biểu thị bằng một hoặc nhiều byte.

Ví dụ về bộ ký tự: ASCII (bao gồm tất cả các ký tự tiếng Anh), ISO / IEC 646, Unicode (bao gồm các ký tự từ tất cả các ngôn ngữ sống trên thế giới)

Bộ ký tự được mã hóa

Một bộ ký tự được mã hóa là một bộ trong đó một số duy nhất được gán cho mỗi ký tự. Số duy nhất đó được gọi là "điểm mã".
Bộ ký tự được mã hóa đôi khi được gọi là trang mã.

Mã hóa

Mã hóa là cơ chế để ánh xạ các điểm mã với một số byte để một ký tự có thể được đọc và viết thống nhất trên các hệ thống khác nhau bằng cách sử dụng cùng một sơ đồ mã hóa.

Ví dụ về mã hóa: ASCII, các sơ đồ mã hóa Unicode như UTF-8, UTF-16, UTF-32.

Xây dựng 3 khái niệm trên

  • Hãy xem xét điều này - Ký tự 'र' trong bộ ký tự Devanagari có điểm mã thập phân là 2325 sẽ được biểu thị bằng hai byte ( 09 15) khi sử dụng mã hóa UTF-16
  • Trong “ISO-8859-1” chương trình mã hóa “ü” (điều này là gì, nhưng một nhân vật trong bộ ký tự Latin) được thể hiện dưới dạng giá trị hexa-thập phân của FCthời gian trong “UTF-8” nó thể hiện dưới dạng C3 BCvà UTF-16 như FE FF 00 FC.
  • Các lược đồ mã hóa khác nhau có thể sử dụng cùng một điểm mã để thể hiện các ký tự khác nhau, ví dụ như trong ISO ISO-8859-1, (còn được gọi là Latin1), giá trị điểm mã thập phân cho chữ 'é' là 233. Tuy nhiên, trong ISO 8859-5 , cùng một điểm mã đại diện cho ký tự Cyrillic 'щ'.
  • Mặt khác, một điểm mã duy nhất trong bộ ký tự Unicode thực sự có thể được ánh xạ tới các chuỗi byte khác nhau, tùy thuộc vào mã hóa nào được sử dụng cho tài liệu. Ký tự Devanagari, với mã điểm 2325 (là 915 theo ký hiệu thập lục phân), sẽ được biểu thị bằng hai byte khi sử dụng mã hóa UTF-16 ( 09 15), ba byte với UTF-8 ( E0 A4 95) hoặc bốn byte với UTF-32 ( 00 00 09 15)

11

Một bộ ký tự, hoặc tiết mục nhân vật, chỉ đơn giản là một bộ (một bộ sưu tập không có thứ tự) của các nhân vật. Một bộ ký tự được mã hóa gán một số nguyên ("điểm mã") cho mỗi ký tự trong tiết mục. Mã hóa là một cách biểu diễn các điểm mã rõ ràng dưới dạng một luồng byte.


Đây phải là câu trả lời được chấp nhận. Nó xác định rõ ràng ba khái niệm: bộ ký tự, bộ ký tự được mã hóa và mã hóa.
Marcus Junius Brutus

6

Googled cho nó. http://en.wikipedia.org/wiki/Character_encoding

Sự khác biệt dường như là tinh tế. Thuật ngữ bộ ký tự thực sự không áp dụng cho Unicode. Unicode trải qua một loạt các khái niệm trừu tượng. ký tự trừu tượng -> điểm mã -> mã hóa điểm mã thành byte.

Bộ ký tự thực sự bỏ qua điều này và trực tiếp nhảy từ ký tự sang byte. chuỗi byte <-> chuỗi ký tự

Tóm lại, mã hóa: điểm mã -> bộ ký tự byte: ký tự -> byte


5

Một bộ ký tự chỉ là một bộ; nó có chứa, ví dụ như ký hiệu Euro, hoặc nếu không thì không. Đó là tất cả.

Mã hóa là ánh xạ phỏng đoán từ một bộ ký tự thành một bộ số nguyên. Nếu nó hỗ trợ ký hiệu Euro, nó phải gán một số nguyên cụ thể cho ký tự đó và không cho số khác.


Nó có phải là tính từ?
Jörg W Mittag 17/210

2
Chà, mã hóa và giải mã nên mang tính quyết định, vì vậy thực sự không thể có bất kỳ ánh xạ mơ hồ nào. Tôi cho rằng bạn có thể có một bộ số nguyên không liền kề làm tên miền, nhưng điều đó sẽ lãng phí không gian khi bạn lưu trữ văn bản và các kỹ sư ghét không gian lãng phí.
Kilian Foth

1
Mã hóa nhân vật kế thừa thường không phải là tính từ. Ví dụ, trong IBM437, cả ß và được biểu thị bằng 0xE1.
dan04

3

Theo tôi, bộ ký tự là một phần của mã hóa (một thành phần), mã hóa có thuộc tính bộ ký tự, do đó, bộ ký tự có thể được sử dụng trong nhiều bảng mã. Ví dụ unicode là một bộ ký tự được sử dụng trong các bảng mã như UTF-8, UTF-16, v.v. Xem hình minh họa tại đây:Xem hình minh họa tại đây

Char trong bộ ký tự không có nghĩa là loại char trong thế giới lập trình, nó có nghĩa là char trong thế giới thực, trong tiếng Anh nó có thể giống nhau, nhưng trong các ngôn ngữ khác không phải, như tiếng Trung, '我' là một 'char' không thể tách rời trong bộ ký tự (UNICODE, GB [được sử dụng trong GBK và GB2312]), 'a' cũng là một ký tự trong bảng mã (ASCII, ISO-8859 , UNICODE).


1

Theo tôi, từ "bộ ký tự" nên được giới hạn trong việc xác định tham số được sử dụng trong HTTP, MIME và các tiêu chuẩn tương tự để chỉ định mã hóa ký tự (ánh xạ từ một chuỗi ký tự văn bản thành chuỗi byte) theo tên. Ví dụ:charset=utf-8 .

Tuy nhiên, tôi biết rằng MySQL, Java và các nơi khác có thể sử dụng từ "bộ ký tự" để chỉ mã hóa ký tự.


1

Mã hóa là ánh xạ giữa byte và ký tự từ một bộ ký tự, vì vậy sẽ rất hữu ích khi thảo luận và hiểu sự khác biệt giữa byteký tự .

Hãy nghĩ về byte là các số từ 0 đến 255, trong khi các ký tự là những thứ trừu tượng như "a", "1", "$" và "". Tập hợp tất cả các ký tự có sẵn được gọi là một bộ ký tự .

Mỗi ký tự có một chuỗi gồm một hoặc nhiều byte được sử dụng để thể hiện nó; tuy nhiên, số lượng và giá trị chính xác của các byte phụ thuộc vào mã hóa được sử dụng và có nhiều mã hóa khác nhau.

Hầu hết các mã hóa dựa trên một bộ ký tự cũ và mã hóa được gọi là ASCII, một byte cho mỗi ký tự (thực tế, chỉ có 7 bit) và chứa 128 ký tự bao gồm rất nhiều ký tự phổ biến được sử dụng trong tiếng Anh Mỹ.

Ví dụ: đây là 6 ký tự trong bộ ký tự ASCII được biểu thị bằng các giá trị 60 đến 65.

Extract of ASCII Table 60-65
╔══════╦══════════════╗
║ Byte ║  Character   ║
╠══════╬══════════════║
║  60  ║      <       ║
║  61  ║      =       ║
║  62  ║      >       ║
║  63  ║      ?       ║
║  64  ║      @       ║
║  65  ║      A       ║
╚══════╩══════════════╝

Trong bộ ASCII đầy đủ, giá trị thấp nhất được sử dụng là 0 và cao nhất là 127 (cả hai đều là các ký tự điều khiển ẩn).

Tuy nhiên, một khi bạn bắt đầu cần nhiều ký tự hơn ASCII cơ bản cung cấp (ví dụ: các chữ cái có dấu, ký hiệu tiền tệ, ký hiệu đồ họa, v.v.), ASCII không phù hợp và bạn cần một cái gì đó rộng rãi hơn. Bạn cần nhiều ký tự hơn (một bộ ký tự khác) và bạn cần mã hóa khác vì 128 ký tự là không đủ để phù hợp với tất cả các ký tự. Một số mã hóa cung cấp một byte (256 ký tự) hoặc tối đa sáu byte.

Theo thời gian rất nhiều mã hóa đã được tạo ra. Trong thế giới Windows, có CP1252 hoặc ISO-8859-1, trong khi người dùng Linux có xu hướng ủng hộ UTF-8. Java sử dụng UTF-16 nguyên bản.

Một chuỗi các giá trị byte cho một ký tự trong một mã hóa có thể đại diện cho một ký tự hoàn toàn khác trong một mã hóa khác, hoặc thậm chí có thể không hợp lệ.

Ví dụ, trong ISO 8859-1 , â được biểu thị bằng một byte giá trị 226, trong khi ở UTF-8, nó là hai byte : 195, 162. Tuy nhiên, trong ISO 8859-1 , 195, 162sẽ có hai ký tự, Ã, ,.

Khi máy tính lưu trữ dữ liệu về các ký tự bên trong hoặc truyền nó sang hệ thống khác, chúng sẽ lưu trữ hoặc gửi byte. Hãy tưởng tượng một hệ thống mở tệp hoặc nhận tin nhắn sẽ thấy các byte195, 162 . Làm thế nào để nó biết những nhân vật này là gì?

Để hệ thống diễn giải các byte đó thành các ký tự thực tế (và do đó hiển thị chúng hoặc chuyển đổi chúng sang mã hóa khác), nó cần phải biết mã hóa được sử dụng. Đó là lý do tại sao mã hóa xuất hiện trong các tiêu đề XML hoặc có thể được chỉ định trong trình soạn thảo văn bản. Nó cho hệ thống ánh xạ giữa byte và ký tự.

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.