Tại sao các ký tự tiếng Anh yêu cầu ít byte hơn để biểu diễn hơn các bảng chữ cái khác?


31

Khi tôi đặt 'a' trong một tệp văn bản, nó tạo thành 2 byte nhưng khi tôi đặt, hãy nói '', đó là một chữ cái trong bảng chữ cái tiếng Armenia, nó tạo thành 3 byte.

Sự khác biệt giữa các bảng chữ cái cho một máy tính là gì?
Tại sao tiếng Anh chiếm ít không gian?


22
Bạn nên đọc bài viết này của người sáng lập StackExchange: joelonsoftware.com/articles/Unicode.html
Eric Lippert

22
Tôi không nghĩ có một thứ gọi là "ký tự tiếng Anh". Họ là người La Mã.
Raphael

5
@Raphael mọi người đều biết những gì anh ấy đang đề cập đến mặc dù. Nhưng thêm tốt đẹp.
Mathias Lykkegaard Lorenzen

1
@Raphael Trên thực tế có nhiều chữ cái La Mã không được sử dụng bằng tiếng Anh và do đó không được bao gồm trong bộ ký tự ASCII. Hầu hết trong số chúng bao gồm các sửa đổi, nhưng chúng vẫn cần thiết để hiển thị chính xác văn bản trong các ngôn ngữ khác nhau có nguồn gốc Latinh khác với tiếng Anh.
Wutaz

7
@Raphael Tôi không nghĩ có những thứ như nhân vật của Roman Roman. Họ là người Latin.
Blacklight Shining

Câu trả lời:


41

Một trong những kế hoạch mã hóa đầu tiên được phát triển để sử dụng trong các máy tính chính là tiêu chuẩn ASCII ( Mã tiêu chuẩn Mỹ để trao đổi thông tin ). Nó được phát triển vào những năm 1960 tại Hoa Kỳ.

Bảng chữ cái tiếng Anh sử dụng một phần của bảng chữ cái Latinh (ví dụ, có một vài từ có dấu trong tiếng Anh). Có 26 chữ cái riêng trong bảng chữ cái đó, không xem xét trường hợp. Và cũng sẽ phải tồn tại các số riêng lẻ và dấu chấm câu trong bất kỳ sơ đồ nào giả vờ mã hóa bảng chữ cái tiếng Anh.

Những năm 1960 cũng là thời điểm mà máy tính không có dung lượng bộ nhớ hoặc dung lượng ổ đĩa mà chúng ta có bây giờ. ASCII được phát triển để trở thành một đại diện tiêu chuẩn của một bảng chữ cái chức năng trên tất cả các máy tính Mỹ. Vào thời điểm đó, quyết định làm cho mỗi ký tự ASCII dài 8 bit (1 byte) được đưa ra do các chi tiết kỹ thuật của thời gian (bài viết trên Wikipedia đề cập đến thực tế là băng đục lỗ giữ 8 bit tại một vị trí tại một thời điểm). Trong thực tế, sơ đồ ASCII ban đầu có thể được truyền bằng 7 bit, tám bit có thể được sử dụng để kiểm tra chẵn lẻ. Các phát triển sau này đã mở rộng lược đồ ASCII ban đầu để bao gồm một số ký tự có dấu, toán học và đầu cuối.

Với sự gia tăng gần đây của việc sử dụng máy tính trên toàn thế giới, ngày càng có nhiều người từ các ngôn ngữ khác nhau truy cập vào máy tính. Điều đó có nghĩa là, đối với mỗi ngôn ngữ, các sơ đồ mã hóa mới phải được phát triển, độc lập với các lược đồ khác, sẽ xung đột nếu được đọc từ các thiết bị đầu cuối ngôn ngữ khác nhau.

Unicode là một giải pháp cho sự tồn tại của các thiết bị đầu cuối khác nhau, bằng cách hợp nhất tất cả các ký tự có ý nghĩa có thể vào một bộ ký tự trừu tượng duy nhất.

UTF-8 là một cách để mã hóa bộ ký tự Unicode. Nó là một mã hóa có chiều rộng thay đổi (ví dụ: các ký tự khác nhau có thể có kích thước khác nhau) và nó được thiết kế để tương thích ngược với sơ đồ ASCII trước đây. Như vậy, bộ ký tự ASCII sẽ vẫn là một byte lớn trong khi bất kỳ ký tự nào khác lớn hơn hai byte. UTF-16 là một cách khác để mã hóa bộ ký tự Unicode. So với UTF-8, các ký tự được mã hóa dưới dạng một tập hợp một hoặc hai đơn vị mã 16 bit.

Như đã nêu trên các nhận xét, ký tự 'a' chiếm một byte đơn trong khi 'ա' chiếm hai byte, biểu thị mã hóa UTF-8. Các byte bổ sung trong câu hỏi của bạn là do sự tồn tại của một ký tự dòng mới ở cuối (mà OP đã tìm ra).


26
Không có byte cuối cùng mã hóa phần cuối của tệp, ở bất kỳ định dạng tệp hoặc mã hóa thông thường nào. Khi một chương trình đọc một tệp, phần cuối của tệp có thể được HĐH báo hiệu theo một cách đặc biệt, nhưng đó là một vấn đề khác.
Jukka K. Korpela

2
Ký tự is là 2 byte (0xD5A1) trong phiên bản UTF-8 của unicode; ký tự phụ (bất kể là gì) có trong cả hai tệp. marathon-studios.com/unicode/U0561/Armenian_Small_Letter_Ayb
Dan Neely

6
@khajvah Nếu bạn echo 'ա' > file.txt, hoặc chỉnh sửa tệp bằng một số trình chỉnh sửa, họ sẽ tự động thêm một dòng mới sau nó. Nếu bạn chạy xxd file.txt, byte cuối cùng có thể sẽ là một 0ahoặc nguồn cấp dữ liệu.
Daniel Beck

7
@DoktoroReichard: Vui lòng làm rõ trong câu trả lời rằng Unicode không phải là mã hóa; đúng hơn, đó là một bộ ký tự trừu tượng và UTF-16 và UTF-8 là mã hóa của các bảng mã Unicode. Các đoạn cuối của câu trả lời của bạn chủ yếu nói về UTF-8. Nhưng nếu một tệp sử dụng UTF-16, thì bất kỳ mật mã nào, thậm chí là mã cho a, sẽ sử dụng hai byte (hoặc bội số của hai).
grawity

6
Có lẽ cũng đáng nhấn mạnh rằng các bộ ký tự "ASCII mở rộng" trên thực tế hoàn toàn không phải là ASCII, và số cách khác nhau để sử dụng bit thứ tám làm cho tất cả trở nên rắc rối. Chỉ cần sử dụng UTF-8 thay thế.
ntoskrnl

17

1 byte là 8 bit và do đó có thể biểu thị tối đa 256 (2 ^ 8) giá trị khác nhau.

Đối với các ngôn ngữ yêu cầu nhiều khả năng hơn thế này, không thể duy trì ánh xạ 1 đến 1 đơn giản, do đó cần nhiều dữ liệu hơn để lưu trữ một ký tự.

Lưu ý rằng nhìn chung, hầu hết các bảng mã đều sử dụng 7 bit đầu tiên (128 giá trị) cho các ký tự ASCII . Điều đó để lại bit thứ 8, hoặc thêm 128 giá trị cho nhiều ký tự hơn. . . thêm các ký tự có dấu, ngôn ngữ châu Á, Cyrillic, v.v. và bạn có thể dễ dàng thấy tại sao 1 byte không đủ để giữ tất cả các ký tự.


Vì vậy, đây là câu trả lời duy nhất thực sự giải thích tại sao sử dụng nhiều không gian hơn
Félix Gagnon-Grenier

10

Trong UTF-8, các ký tự ASCII sử dụng một byte, các ký tự khác sử dụng hai, ba hoặc bốn byte.


1
Bạn có thể giải thích tại sao điều này là? lưu ý hai phương pháp mã hóa không hoàn toàn trả lời câu hỏi.
MaQleod

@MaQleod Unicode được tạo để thay thế ASCII. Để tương thích ngược, 128 ký tự đầu tiên là như nhau. 128 ký tự này có thể được thể hiện bằng một byte. Byte bổ sung được thêm cho các ký tự bổ sung.
Jason

Tôi biết, nhưng đó là một phần của câu trả lời cho câu hỏi là điều gì làm cho các ký tự ASCII khác nhau. Nó sẽ được giải thích cho OP.
MaQleod

@MaQleod Cũng có thể nói rằng Hiệp hội Unicode hầu hết bao gồm các tập đoàn của Mỹ và thiên về các ký tự tiếng Anh. Tôi nghĩ rằng một câu trả lời đơn giản là tốt hơn một câu trả lời chủ quan.
Jason

15
Không phải "bằng Unicode", trong UTF8 - đây chỉ là một trong một số mã hóa của bộ ký tự Unicode.
Sebastian Negraszus

3

Lượng byte cần thiết cho một ký tự (mà câu hỏi rõ ràng là về) phụ thuộc vào mã hóa ký tự. Nếu bạn sử dụng mã hóa ArmSCII, mỗi chữ cái tiếng Armenia chỉ chiếm một byte. Nó không phải là một lựa chọn tốt những ngày này, mặc dù.

Trong mã hóa chuyển UTF-8 cho Unicode, các ký tự cần một số byte khác nhau. Trong đó, một bộ dữ liệu chỉ mất một byte (ý tưởng về hai byte là một sự nhầm lẫn nào đó), Tiếng á lấy hai byte và chữ cái tiếng Armenia ayb ա ա cũng mất hai byte. Ba byte phải là một loại nhầm lẫn. Ngược lại, ví dụ, thư tiếng Bengal, một “takes có ba byte trong UTF-8.

Bối cảnh đơn giản là UTF-8 được thiết kế rất hiệu quả cho các ký tự Ascii, khá hiệu quả đối với các hệ thống chữ viết ở châu Âu và môi trường xung quanh, và tất cả phần còn lại đều kém hiệu quả. Điều này có nghĩa là các chữ cái Latinh cơ bản (là những gì văn bản tiếng Anh chủ yếu bao gồm), chỉ cần một byte cho một ký tự; đối với tiếng Hy Lạp, Cyrillic, Armenia và một vài thứ khác, cần hai byte; tất cả những thứ còn lại cần nhiều hơn

UTF-8 cũng (như đã chỉ ra trong một nhận xét) cũng là thuộc tính hữu ích mà dữ liệu Ascii (khi được biểu thị dưới dạng đơn vị 8 bit, gần như là cách duy nhất trong một thời gian dài) cũng được mã hóa một cách tầm thường.


Cảm ơn bạn đã trả lời. Các byte bổ sung là do chương trình tôi đã sử dụng tự động thêm ký tự dòng mới vào cuối.
khajvah

1
Tôi không nghĩ UTF-8 được thiết kế nhiều để đạt hiệu quả với dữ liệu ASCII như tính tương thích . UTF-8 có một đặc tính rất hay là nội dung ASCII 7 bit (với bit cao được đặt thành 0) giống hệt với nội dung được mã hóa như UTF-8, do đó, đối với các công cụ thường xử lý ASCII, đó là một công cụ thay thế thả xuống . Theo tôi, không có sơ đồ mã hóa Unicode nào có thuộc tính đó. UTF-8 cũng nhỏ gọn hợp lý cho hầu hết các dữ liệu, đặc biệt nếu bạn ở trong vương quốc của Unicode BMP .
CVn

1
@ MichaelKjorling, tôi đã thêm một tham chiếu đến tính năng đó. Tuy nhiên, một sự phản đối lớn đối với Unicode trong những ngày đầu là không hiệu quả và UTF-16 tăng gấp đôi kích thước của dữ liệu mà chủ yếu là Ascii. UTF-8 có nghĩa là, ví dụ như đối với văn bản tiếng Anh, rằng bạn chỉ phải trả tiền cho các ký tự không phải là chữ Asii mà bạn sử dụng.
Jukka K. Korpela

3

Mã ký tự trong những năm 1960 (và xa hơn nữa) là đặc thù của máy. Vào những năm 1980, tôi đã sử dụng ngắn gọn một máy tháng 12 năm 2020, có các từ 36 bit và 5, 6 và 8 ( IIRC ) cho mỗi mã hóa ký tự. Trước đó, tôi đã sử dụng một loạt IBM 370 với EBCDIC. ASCII với 7 bit được sắp xếp theo thứ tự, nhưng nó có một mớ hỗn độn với "bộ mã" IBM PC sử dụng tất cả 8 bit để thể hiện các ký tự phụ, giống như tất cả các loại hình vẽ hộp để vẽ các menu nguyên thủy và các phần mở rộng ASCII sau này như Latin-1 (8 bit mã hóa, với 7 bit đầu tiên như ASCII và nửa còn lại cho "nhân vật quốc gia" như ñ, Çhoặc những người khác. có lẽ phổ biến nhất là Latin-1, phù hợp với tiếng Anh và hầu hết các ngôn ngữ châu Âu sử dụng ký tự Latin (và các điểm nhấn và biến thể).

Viết văn bản trộn, ví dụ tiếng Anh và tiếng Tây Ban Nha đều ổn (chỉ sử dụng tiếng Latin-1, siêu âm của cả hai), nhưng pha trộn bất cứ thứ gì sử dụng mã hóa khác nhau (nói bao gồm một đoạn tiếng Hy Lạp hoặc tiếng Nga, không đề cập đến một ngôn ngữ châu Á như tiếng Nhật) một cơn ác mộng thật sự. Tệ nhất là tiếng Nga và đặc biệt là Nhật Bản và Trung Quốc có một số mã hóa phổ biến, hoàn toàn không tương thích.

Ngày nay, chúng tôi sử dụng Unicode, được mã hóa thành mã hóa hiệu quả như UTF-8 thiên về các ký tự tiếng Anh (đáng ngạc nhiên, mã hóa cho các chữ cái tiếng Anh chỉ xảy ra tương ứng với ASCII), do đó làm cho nhiều ký tự không phải tiếng Anh sử dụng mã hóa dài hơn.


2

Windows 8.1 US / English File với một 'a' được lưu bằng notepad.

  • Lưu AS ANSI 1 byte
  • Lưu AS Unicode 4 byte
  • Lưu AS UTF-8 4 byte

Tệp có một 'ա' được lưu bằng notepad

  • Không thể lưu AS ANSI
  • Lưu AS Unicode 4 byte
  • Lưu AS UTF-8 5 byte

Một 'a' được mã hóa dưới dạng một byte đơn trong ANSI, trong Unicode, mỗi ký tự thường là 2 byte cũng có BOM 2 byte (Dấu đánh dấu thứ tự Byte) ở đầu tệp. UTF-8 có BOM 3 byte và ký tự byte đơn.

Đối với '', ký tự đó không tồn tại trong bộ ký tự ANSI và không thể lưu trong máy của tôi. Tệp Unicode giống như trước đây và tệp UTF-8 lớn hơn 1 byte khi ký tự mất 2 byte.

Nếu máy của bạn đến từ một khu vực khác, bạn có thể có một trang mã OEM khác được cài đặt có các glyph khác nhau cho 255 ký tự có thể có trong phạm vi ASCII. Như @ntoskrnl đã đề cập đến bảng mã OEM cho máy của tôi sẽ là Windows-1252, mặc định cho tiếng Anh Mỹ.


4
Notepad (và Windows nói chung) sử dụng thuật ngữ khó hiểu ở đây. "ANSI" là một mã hóa byte đơn phụ thuộc vào miền địa phương (Windows-1252 trên các phiên bản tiếng Anh) và "Unicode" là UTF-16.
ntoskrnl

@ntoskrnl Điều đó đúng, nhưng nếu bạn đang tìm kiếm trong hộp thả để mã hóa thì nó nói là ANSI, đó là lý do tại sao tôi đã đề cập nếu bạn có một bảng mã OEM khác, bạn có thể nhận được các kết quả khác nhau.
Darryl Braaten

2

Nếu bạn quan tâm đến cách các ký tự được lưu trữ, bạn có thể truy cập www.unicode.org và xem xung quanh. Ở đầu trang chính của họ là liên kết "Biểu đồ mã" hiển thị cho bạn tất cả các mã ký tự có sẵn bằng Unicode.

Nói chung, có hơn một triệu mã có sẵn trong Unicode (không phải tất cả chúng đều được sử dụng). Một byte có thể chứa 256 giá trị khác nhau, vì vậy bạn sẽ cần ba byte nếu bạn muốn lưu trữ mọi mã Unicode có thể.

Thay vào đó, Unicode thường được lưu trữ trong mã hóa "UTF-8", sử dụng ít byte hơn cho một số ký tự và nhiều hơn cho các ký tự khác. 128 giá trị mã đầu tiên được lưu trữ trong một byte đơn, tối đa 2048 giá trị mã đầu tiên được lưu trữ trong hai byte, tối đa 65536 được lưu trữ trong ba byte và phần còn lại mất bốn byte. Điều này đã được sắp xếp sao cho các giá trị mã được sử dụng thường chiếm ít không gian hơn. AZ, az, 0-9 và! @ $% ^ & * () - [} {}; ': "|,. / <>? Và một số mà tôi quên mất một byte, gần như toàn bộ tiếng Anh, 98% Tiếng Đức và tiếng Pháp (chỉ cần đoán) có thể được lưu trữ trong một byte cho mỗi ký tự và đây là những ký tự được sử dụng nhiều nhất. Cyrillic, Hy Lạp, tiếng Do Thái, tiếng Ả Rập và một số người khác sử dụng hai byte cho mỗi ký tự. , Hàn Quốc, Thái Lan, tấn biểu tượng toán học, có thể được viết bằng ba byte cho mỗi ký tự. Những thứ hiếm (nếu bạn muốn viết văn bản trong Tuyến tính A hoặc Tuyến tính B, Biểu tượng cảm xúc) mất bốn byte.

Một mã hóa khác là UTF-16. Mọi thứ cần 1, 2 hoặc 3 byte trong UTF-8 đều mất hai byte trong UTF-16. Đó là một lợi thế nếu bạn có văn bản tiếng Trung hoặc tiếng Nhật với rất ít ký tự Latin ở giữa.

Về các lý do cho thiết kế UTF-8: Nó có một số lợi thế so với các thiết kế khác. Họ đang:

Khả năng tương thích với các ký tự US-ASCII

Nhỏ gọn hợp lý

Tự đồng bộ hóa: Điều này có nghĩa là nếu bạn được cung cấp một phần của chuỗi byte là các ký tự trong mã hóa UTF-8, bạn có thể tìm ra nơi ký tự bắt đầu. Trong một số mã hóa, cả xy và yx đều có thể là mã hóa hợp lệ của các ký tự, vì vậy nếu bạn được cung cấp một phần của chuỗi ... xyxyxyxyxyxy ... bạn không thể biết mình có ký tự nào.

Sắp xếp chính xác: Nếu bạn sắp xếp các chuỗi chứa các ký tự được mã hóa UTF-8 theo các giá trị byte của chúng, thì chúng sẽ tự động được sắp xếp chính xác theo các giá trị Unicode của chúng.

Tương thích với mã byte đơn: Hầu hết các mã giả định các giá trị byte đơn hoạt động chính xác với các ký tự được mã hóa UTF-8.

Cộng với bất cứ lý do gì tôi quên.

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.