Lợi thế của việc chọn mã hóa ASCII so với UTF-8 là gì?


91

Tất cả các ký tự trong ASCII có thể được mã hóa bằng UTF-8 mà không tăng dung lượng lưu trữ (cả hai đều yêu cầu một byte lưu trữ).

UTF-8 có thêm lợi ích hỗ trợ ký tự ngoài "ký tự ASCII". Nếu đó là trường hợp, tại sao sẽ chúng tôi từng chọn mã hóa ASCII qua UTF-8?

Có trường hợp sử dụng nào khi chúng ta sẽ chọn ASCII thay vì UTF-8 không?


9
Để hỗ trợ công cụ kế thừa ...
fretje

9
ý tôi là UTF8 cũng hỗ trợ ASCII một cách hợp pháp. vì vậy ngay cả khi bạn phải hỗ trợ các công cụ cũ, UTF8 sẽ hoạt động tốt, không có thay đổi nào khác cần thiết.
Pacerier

3
Có lẽ bạn đã phải tương tác với một hệ thống chứa 8 ký tự ASCII thành 7 byte? Mọi người đã làm những thứ điên rồ để phù hợp với mọi thứ.
Donal Fellows 31/07

4
Gọi tôi là hạt dẻ, nhưng tôi muốn nói là an ninh và ổn định. Một bộ ký tự không có chuỗi nhiều byte sẽ khó phá vỡ hơn rất nhiều. Đừng hiểu sai ý tôi, khi hỗ trợ ngôn ngữ của con người là quan trọng ASCII sẽ không cắt giảm. Nhưng nếu bạn chỉ đang thực hiện một số chương trình cơ bản và có thể ép mình vào ngôn ngữ bản địa thì trình biên dịch và hệ điều hành đã được viết, tại sao lại thêm sự phức tạp? @ Nghiên cứu sinh. Lần cuối tôi kiểm tra ... ASCII 7 byte. (bất cứ điều gì có thêm bit đó không phải là ASCII và đang yêu cầu sự cố)
ebyrob

2
@wiserob Tôi nghĩ Donal Fellows có nghĩa là bit đóng gói 8 ký hiệu ascii thành 7 byte, vì mỗi ký hiệu đang sử dụng 7 bit mỗi ... 8 * 7 = 56 bit = 7 byte. Nó có nghĩa là một chức năng mã hóa và giải mã đặc biệt, chỉ để lưu 1 byte dung lượng lưu trữ trong mỗi 8.
dodgy_coder

Câu trả lời:


83

Trong một số trường hợp, nó có thể tăng tốc độ truy cập vào từng ký tự. Tưởng tượng chuỗi str='ABC'được mã hóa trong UTF8 và ASCII (và giả sử rằng ngôn ngữ / trình biên dịch / cơ sở dữ liệu biết về mã hóa)

Để truy cập Cký tự thứ ba ( ) từ chuỗi này bằng toán tử truy cập mảng, đặc trưng trong nhiều ngôn ngữ lập trình, bạn sẽ làm một cái gì đó như c = str[2].

Bây giờ, nếu chuỗi được mã hóa ASCII, tất cả những gì chúng ta cần làm là tìm nạp byte thứ ba từ chuỗi.

Tuy nhiên, nếu chuỗi được mã hóa UTF-8, trước tiên chúng ta phải kiểm tra xem ký tự đầu tiên là char một hay hai byte, sau đó chúng ta cần thực hiện kiểm tra tương tự trên ký tự thứ hai và chỉ sau đó chúng ta mới có thể truy cập ký tự thứ ba. Sự khác biệt về hiệu suất sẽ càng lớn, chuỗi càng dài.

Đây là một vấn đề ví dụ trong một số công cụ cơ sở dữ liệu, nơi tìm thấy phần đầu của cột được đặt 'sau' VARCHAR được mã hóa UTF-8, cơ sở dữ liệu không chỉ cần kiểm tra có bao nhiêu ký tự trong trường VARCHAR, mà còn nhiều byte mỗi một trong số họ sử dụng.


3
Nếu cơ sở dữ liệu không lưu trữ cả "số ký tự" "số byte", thì tôi sẽ nói rằng nó có một số vấn đề ...
Dean Harding

1
TBH Tôi biết không có cơ sở dữ liệu nào sẽ lưu trữ cả ...
Mchl

@Mchl: làm thế nào để bạn tưởng tượng cơ sở dữ liệu biết khi nào nó đã đến cuối chuỗi?
kevin cline

1
Thông thường bằng cách đạt 0x00 hoặc 0x0000
Mchl

4
@DeanHending Làm thế nào để đếm nhân vật cho bạn biết nhân vật thứ hai bắt đầu từ đâu? Hoặc cơ sở dữ liệu nên giữ một chỉ mục cho mỗi ký tự bù? Lưu ý: Đó không chỉ là 2 ký tự, nhưng có thể lên tới 4 (trừ khi 6) stackoverflow.com/questions/9533258/ trộm . (Tôi nghĩ rằng chỉ có utf-16 mới có sự ghê tởm thực sự dài có thể phá hủy hệ thống của bạn)
ebyrob

7

Nếu bạn sẽ chỉ sử dụng tập hợp con US-ASCII (hoặc ISO 646) của UTF-8, thì không có lợi thế thực sự cho cái này hay cái khác; trong thực tế, tất cả mọi thứ được mã hóa giống hệt nhau.

Nếu bạn sẽ vượt ra ngoài bộ ký tự US-ASCII và sử dụng (ví dụ) các ký tự có dấu, âm sắc, v.v., được sử dụng trong các ngôn ngữ Tây Âu điển hình, thì có một sự khác biệt - hầu hết trong số này vẫn có thể được mã hóa với một byte đơn trong ISO 8859, nhưng sẽ yêu cầu hai hoặc nhiều byte khi được mã hóa bằng UTF-8. Tất nhiên cũng có những nhược điểm: ISO 8859 yêu cầu bạn sử dụng một số phương tiện ngoài băng để chỉ định mã hóa đang được sử dụng và nó chỉ hỗ trợ mộtcủa những ngôn ngữ này tại một thời điểm Ví dụ: bạn có thể mã hóa tất cả các ký tự của bảng chữ cái Cyrillic (tiếng Nga, tiếng Belorussian, v.v.) chỉ bằng một ký tự một byte, nhưng nếu bạn cần / muốn trộn chúng với các ký tự tiếng Pháp hoặc tiếng Tây Ban Nha (trừ các ký tự trong US-ASCII / Tập hợp con ISO 646) bạn gặp khá nhiều may mắn - bạn phải thay đổi hoàn toàn bộ ký tự để làm điều đó.

ISO 8859 thực sự chỉ hữu ích cho bảng chữ cái châu Âu. Để hỗ trợ hầu hết các bảng chữ cái được sử dụng trong hầu hết các bảng chữ cái của Trung Quốc, Nhật Bản, Hàn Quốc, Ả Rập, v.v., bạn phải sử dụng một số mã hóa hoàn toàn khác nhau. Một số trong số này (Ví dụ, Shift JIS cho tiếng Nhật) là một nỗi đau tuyệt đối để giải quyết. Nếu có bất kỳ cơ hội nào bạn sẽ muốn hỗ trợ họ, tôi sẽ coi việc sử dụng Unicode chỉ trong trường hợp là đáng giá.


5

ANSI có thể có nhiều thứ, hầu hết là các bộ ký tự 8 bit về vấn đề này (như trang mã 1252 trong Windows).

Có lẽ bạn đã nghĩ về ASCII là 7 bit và một tập hợp con thích hợp của UTF-8. Tức là bất kỳ luồng ASCII hợp lệ nào cũng là luồng UTF-8 hợp lệ.

Nếu bạn đang nghĩ về các bộ ký tự 8 bit, một lợi thế rất quan trọng là tất cả các ký tự có thể biểu diễn chính xác là 8 bit, trong đó trong UTF-8, chúng có thể lên tới 24 bit.


vâng tôi đang nói về bộ ASCII 7 bit. bạn có thể nghĩ về 1 lợi thế mà chúng ta sẽ cần để lưu thứ gì đó như ascii thay vì utf-8 không? (vì dù sao 7 bit sẽ được lưu thành 8 bit, kích thước tệp sẽ hoàn toàn giống nhau)
Pacerier

1
Nếu bạn có các ký tự lớn hơn giá trị unicode 127, chúng không thể được lưu trong ASCII.

1
@Pacerier: Bất kỳ chuỗi ASCII nào cũng là chuỗi UTF-8 , vì vậy không có sự khác biệt . Thói quen mã hóa thể nhanh hơn tùy thuộc vào cách biểu diễn chuỗi của nền tảng bạn sử dụng, mặc dù tôi không mong đợi việc tăng tốc đáng kể, trong khi bạn có sự mất linh hoạt đáng kể.
back2dos

@Thor chính xác là lý do tại sao tôi hỏi nếu tiết kiệm như ASCII có bất kỳ lợi thế nào không
Pacerier

5
@Pacerier, nếu bạn lưu XML dưới dạng ASCII, bạn cần sử dụng, ví dụ & # 160; cho một không gian không thể phá vỡ. Điều này được lấp đầy hơn, nhưng làm cho dữ liệu của bạn có khả năng chống lại các lỗi mã hóa ISO-Latin-1 so với UTF-8 nhiều hơn. Đây là những gì chúng tôi làm khi nền tảng cơ bản của chúng tôi thực hiện rất nhiều phép thuật vô hình với các nhân vật. Ở trong ASCII làm cho dữ liệu của chúng tôi mạnh mẽ hơn.

3

Có, vẫn còn một số trường hợp sử dụng trong đó ASCII có ý nghĩa: định dạng tệpgiao thức mạng . Đặc biệt, để sử dụng trong đó:

  • Bạn có dữ liệu được tạo và sử dụng bởi các chương trình máy tính, không bao giờ được trình bày cho người dùng cuối;
  • Nhưng nó hữu ích cho các lập trình viên để có thể đọc, để dễ dàng phát triển và gỡ lỗi.

Bằng cách sử dụng ASCII làm mã hóa, bạn tránh được sự phức tạp của mã hóa nhiều byte trong khi vẫn giữ được ít nhất khả năng đọc của con người.

Một vài ví dụ:

  • HTTP là một giao thức mạng được định nghĩa theo các chuỗi octet, nhưng nó rất hữu ích (ít nhất là đối với các lập trình viên nói tiếng Anh), chúng tương ứng với mã hóa ASCII của các từ như "GET", "POST", "Ngôn ngữ chấp nhận" và Sớm.
  • Các loại khối trong định dạng hình ảnh PNG bao gồm bốn octet, nhưng thật tiện dụng nếu bạn đang lập trình một bộ mã hóa hoặc bộ giải mã PNG IDATcó nghĩa là "dữ liệu hình ảnh" và PLTEcó nghĩa là "bảng màu".

Tất nhiên bạn cần cẩn thận rằng dữ liệu thực sự sẽ không được trình bày cho người dùng cuối, bởi vì nếu nó kết thúc hiển thị (như đã xảy ra trong trường hợp URL), thì người dùng sẽ mong đợi dữ liệu đó đúng trong một ngôn ngữ họ có thể đọc.


Nói hay lắm. Có một chút mỉa mai rằng HTTP, giao thức truyền mã unicode nhất trên hành tinh chỉ cần hỗ trợ ASCII. (Trên thực tế, tôi cho rằng điều tương tự cũng xảy ra với TCP và IP, hỗ trợ nhị phân, hỗ trợ ASCII ... đó là tất cả những gì bạn cần ở cấp độ đó)
ebyrob

2

Trước hết: tiêu đề của bạn sử dụng / d ANSI, trong khi trong văn bản bạn đề cập đến ASCII. Xin lưu ý rằng ANSI không bằng ASCII. ANSI kết hợp bộ ASCII. Nhưng bộ ASCII bị giới hạn ở 128 giá trị số đầu tiên (0 - 127).

Nếu tất cả dữ liệu của bạn bị giới hạn ở ASCII (7 bit), việc bạn sử dụng UTF-8, ANSI hay ASCII không thành vấn đề, vì cả ANSI và UTF-8 đều kết hợp bộ ASCII đầy đủ. Nói cách khác: các giá trị số 0 lên đến và bao gồm 127 thể hiện chính xác các ký tự giống nhau trong ASCII, ANSI và UTF-8.

Nếu bạn cần các ký tự bên ngoài bộ ASCII, bạn sẽ cần chọn mã hóa. Bạn có thể sử dụng ANSI, nhưng sau đó bạn gặp phải các vấn đề của tất cả các trang mã khác nhau. Tạo một tệp trên máy A và đọc nó trên máy B có thể / sẽ tạo ra các văn bản trông buồn cười nếu các máy này được thiết lập để sử dụng các trang mã khác nhau, đơn giản vì giá trị số nnn đại diện cho các ký tự khác nhau trong các trang mã này.

"Địa ngục trang mã" này là lý do tại sao tiêu chuẩn Unicode được xác định. UTF-8 là một mã hóa duy nhất của tiêu chuẩn đó, còn nhiều thứ nữa. UTF-16 được sử dụng rộng rãi nhất vì nó là mã hóa riêng cho Windows.

Vì vậy, nếu bạn cần hỗ trợ bất cứ điều gì ngoài 128 ký tự của bộ ASCII, lời khuyên của tôi là hãy sử dụng UTF-8 . Bằng cách đó, điều đó không thành vấn đề và bạn không phải lo lắng về việc trang nào mà người dùng của bạn đã thiết lập hệ thống của họ.


Nếu tôi không cần hỗ trợ ngoài 128 ký tự, lợi thế của việc chọn mã hóa ACSII so với mã hóa UTF8 là gì?
Pacerier

Bên cạnh việc giới hạn bản thân với 128 ký tự đó? Không nhiều. UTF-8 được thiết kế đặc biệt để phục vụ cho ASCII và hầu hết các ngôn ngữ phương Tây "chỉ" cần ANSI. Bạn sẽ thấy rằng UTF-8 sẽ chỉ mã hóa một số lượng tương đối nhỏ các ký tự ANSI cao hơn có nhiều hơn một byte. Có một lý do khiến hầu hết các trang HTML sử dụng UTF-8 làm mặc định ...
Marjan Venema

1
@Pacerier, nếu bạn không cần mã hóa trên 127, việc chọn ASCII có thể có giá trị khi bạn sử dụng một số API để mã hóa / giải mã, vì UTF cần xác minh bit bổ sung để xem xét các byte bổ sung như cùng một ký tự, nó có thể tính toán bổ sung thay vì ASCII thuần túy chỉ đọc 8 bit mà không cần xác minh. Nhưng tôi chỉ khuyên bạn nên sử dụng ASCII nếu bạn thực sự cần mức độ tối ưu hóa cao trong tính toán lớn (lớn lớn) và bạn biết bạn đang làm gì trong tối ưu hóa đó. Nếu không, chỉ cần sử dụng UTF-8.
Luciano
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.