Jaka jest zaleta wyboru kodowania ASCII zamiast UTF-8?

91

Wszystkie znaki w ASCII mogą być kodowane za pomocą UTF-8 bez zwiększania pamięci (oba wymagają bajtu pamięci).

UTF-8 ma dodatkową zaletę obsługi postaci poza „znakami ASCII”. Jeśli tak, to dlaczego kiedykolwiek wybieramy kodowanie ASCII zamiast UTF-8?

Czy istnieje przypadek użycia, w którym wybieramy ASCII zamiast UTF-8?

Pacerier
źródło
9
Aby wesprzeć starsze rzeczy ...
fretje
9
Mam na myśli UTF8 jest legacily wspiera ASCII też. więc nawet jeśli musisz obsługiwać starsze funkcje, UTF8 działałby dobrze, żadne inne zmiany nie były potrzebne.
Pacerier
3
Może musisz współpracować z systemem, który pakuje 8 znaków ASCII w 7 bajtów? Ludzie robili szalone rzeczy, żeby je dopasować.
Donal Fellows
4
Nazywaj mnie wariatem, ale powiedziałbym, że bezpieczeństwo i stabilność. Zestaw znaków bez sekwencji wielobajtowych jest znacznie trudniejszy do złamania. Nie zrozumcie mnie źle, gdy obsługa języka ludzkiego jest ważna, ASCII go nie wyciszy. Ale jeśli tylko programujesz i potrafisz wcisnąć się w język ojczysty, dla którego został napisany kompilator i system operacyjny, po co dodawać złożoności? @Donal Fellows. Ostatnio sprawdziłem ... ASCII ma 7 bajtów. (cokolwiek z tym dodatkowym bitem nie jest po prostu ASCII i wymaga kłopotów)
ebyrob
2
@ebyrob Myślę, że Donal Fellows oznacza pakowanie bitów 8 symboli ascii w 7 bajtów, ponieważ każdy symbol używa 7 bitów każdy ... 8 * 7 = 56 bitów = 7 bajtów. Oznaczałoby to specjalną funkcję kodowania i dekodowania, aby zaoszczędzić 1 bajt pamięci na każde 8.
dodgy_coder

Odpowiedzi:

83

W niektórych przypadkach może to przyspieszyć dostęp do poszczególnych postaci. Wyobraź sobie łańcuch str='ABC'zakodowany w UTF8 i ASCII (i zakładając, że język / kompilator / baza danych wie o kodowaniu)

Aby uzyskać dostęp do trzeciego Cznaku ( ) z tego ciągu za pomocą operatora dostępu do tablicy, który występuje w wielu językach programowania, zrobiłbyś coś takiego c = str[2].

Teraz, jeśli ciąg jest zakodowany w ASCII, wystarczy pobrać trzeci bajt z ciągu.

Jeśli jednak łańcuch znaków jest zakodowany w UTF-8, musimy najpierw sprawdzić, czy pierwszy znak jest jedno- lub dwubajtowym char, następnie musimy wykonać to samo sprawdzenie drugiego znaku i tylko wtedy możemy uzyskać dostęp do trzeciego znaku. Różnica w wydajności będzie tym większa, im dłuższa będzie struna.

Jest to problem na przykład w niektórych silnikach baz danych, gdzie aby znaleźć początek kolumny umieszczonej „po” VARCHAR zakodowanym w UTF-8, baza danych musi nie tylko sprawdzić, ile znaków jest w polu VARCHAR, ale także jak wiele bajtów, z których korzysta każdy z nich.

Mchl
źródło
3
Jeśli baza danych nie przechowuje zarówno „liczby znaków”, jak i „liczby bajtów”, powiedziałbym, że ma pewne problemy ...
Dean Harding
1
TBH Nie znam żadnej bazy danych, która przechowywałaby albo ...
Mchl
@Mchl: jak wyobrażasz sobie, że baza danych wie, kiedy osiągnęła koniec ciągu?
kevin cline
1
Zazwyczaj osiągając 0x00 lub 0x0000
Mchl
4
@DeanHarding W jaki sposób liczba znaków mówi ci, gdzie zaczyna się druga postać? A może baza danych powinna również zawierać indeks dla każdego przesunięcia znaku? Uwaga: To nie jest tylko 2 znaki, ale może wynosić do 4 (chyba, kiedy to 6) stackoverflow.com/questions/9533258/... . (Myślę, że tylko utf-16 miał naprawdę długie obrzydliwości, które mogły zniszczyć twój system)
ebyrob
7

Jeśli zamierzasz używać tylko podzestawu US-ASCII (lub ISO 646) UTF-8, to nie ma żadnej realnej korzyści dla jednego lub drugiego; w rzeczywistości wszystko jest kodowane identycznie.

Jeśli zamierzasz wyjść poza zestaw znaków US-ASCII i używać (na przykład) znaków z akcentami, umlautów itp., Które są używane w typowych językach Europy Zachodniej, to jest różnica - większość z nich może nadal być zakodowany jednym bajtem w ISO 8859, ale będzie wymagał dwóch lub więcej bajtów, gdy jest zakodowany w UTF-8. Są też oczywiście wady: ISO 8859 wymaga użycia pewnych środków poza pasmem, aby określić używane kodowanie, i obsługuje tylko jedenz tych języków jednocześnie. Na przykład możesz zakodować wszystkie znaki alfabetu cyrylicy (rosyjski, białoruski itp.) Przy użyciu tylko jednego bajtu, ale jeśli chcesz / chcesz mieszać je ze znakami francuskimi lub hiszpańskimi (innymi niż te w US-ASCII / Podzbiór ISO 646) nie masz szczęścia - musisz całkowicie zmienić zestawy znaków, aby to zrobić.

ISO 8859 jest naprawdę przydatny tylko dla europejskich alfabetów. Aby obsługiwać większość alfabetów używanych w większości alfabetów chińskich, japońskich, koreańskich, arabskich itp., Musisz użyć zupełnie innego kodowania. Niektóre z nich (np. Shift JIS w języku japońskim) są absolutnym bólem. Jeśli jest jakaś szansa, że ​​kiedykolwiek będziesz chciał je wesprzeć, uważam, że warto na wszelki wypadek użyć Unicode.

Jerry Coffin
źródło
5

ANSI może mieć wiele cech, z których większość to 8-bitowe zestawy znaków w tym względzie (np. Strona kodowa 1252 w systemie Windows).

Być może myślałeś o ASCII, który jest 7-bitowy i jest odpowiednim podzbiorem UTF-8. Oznacza to, że każdy prawidłowy strumień ASCII jest również prawidłowym strumieniem UTF-8.

Jeśli myślisz o 8-bitowych zestawach znaków, jedną bardzo ważną zaletą byłoby to, że wszystkie reprezentowalne znaki mają dokładnie 8 bitów, podczas gdy w UTF-8 mogą mieć do 24 bitów.


źródło
tak, mówię o 7-bitowym zestawie ASCII. czy możesz pomyśleć o jednej korzyści, że kiedykolwiek będziemy musieli zapisać coś jako ascii zamiast utf-8? (ponieważ 7-bitowy i tak zostanie zapisany jako 8-bitowy, rozmiar pliku byłby dokładnie taki sam)
Pacerier
1
Jeśli masz znaki większe niż wartość Unicode 127, nie można ich zapisać w ASCII.
1
@Pacerier: Dowolny ciąg ASCII jest ciągiem UTF-8 , więc nie ma różnicy . Procedura kodowania może być szybsza w zależności od reprezentacji łańcucha używanej platformy, chociaż nie spodziewałbym się znacznego przyspieszenia, podczas gdy masz znaczną utratę elastyczności.
back2dos
@Thor właśnie dlatego pytam, czy oszczędzanie jako ASCII ma w ogóle jakieś zalety
Pacerier
5
@Pacerier, jeśli zapisujesz XML jako ASCII, musisz użyć np. & # 160; dla niezniszczalnej przestrzeni. Jest to więcej danych, ale zwiększa odporność danych na błędy kodowania ISO-Latin-1 w porównaniu z błędami kodowania UTF-8. To właśnie robimy, ponieważ nasza podstawowa platforma wykonuje wiele niewidzialnej magii z postaciami. Pobyt w ASCII sprawia, że ​​nasze dane są bardziej niezawodne.
3

Tak, wciąż istnieją przypadki użycia, w których ASCII ma sens: formaty plików i protokoły sieciowe . W szczególności do zastosowań, w których:

  • Masz dane generowane i konsumowane przez programy komputerowe, nigdy nie przedstawiane użytkownikom końcowym;
  • Ale co jest przydatne dla programistów, aby móc czytać, dla ułatwienia programowania i debugowania.

Używając ASCII jako kodowania, unikasz złożoności kodowania wielobajtowego, zachowując co najmniej pewną czytelność dla człowieka.

Kilka przykładów:

  • HTTP jest protokołem sieciowym zdefiniowanym za pomocą sekwencji oktetów, ale bardzo przydatne (przynajmniej dla programistów anglojęzycznych) jest to, że odpowiadają one kodowaniu ASCII słów takich jak „GET”, „POST”, „Accept-Language” i wkrótce.
  • Te typy chunk w formacie PNG składa się z czterech oktetów, ale jest to przydatne, jeśli jesteś programowania kodera PNG lub dekoder, który IDAToznacza „dane obrazu”, a PLTEoznacza „palety”.

Oczywiście musisz uważać, aby dane naprawdę nie były prezentowane użytkownikom końcowym, ponieważ jeśli ostatecznie będą widoczne (jak to miało miejsce w przypadku adresów URL), użytkownicy słusznie oczekują, że te dane będą w języku, który potrafią czytać.

Gareth Rees
źródło
Dobrze powiedziane. To trochę ironiczne, że HTTP, protokół, który przesyła najbardziej unikodowy kod na świecie, musi obsługiwać tylko ASCII. (Właściwie to samo dotyczy TCP i IP, wsparcia binarnego, wsparcia ASCII ... to wszystko, czego potrzebujesz na tym poziomie stosu)
ebyrob
2

Po pierwsze: twój tytuł używa / d ANSI, podczas gdy w tekście odwołujesz się do ASCII. Należy pamiętać, że ANSI nie równa się ASCII. ANSI zawiera zestaw ASCII. Ale zestaw ASCII jest ograniczony do pierwszych 128 wartości liczbowych (0–127).

Jeśli wszystkie twoje dane są ograniczone do ASCII (7-bit), nie ma znaczenia, czy używasz UTF-8, ANSI czy ASCII, ponieważ zarówno ANSI, jak i UTF-8 zawierają pełny zestaw ASCII. Innymi słowy: wartości liczbowe od 0 do 127 włącznie reprezentują dokładnie takie same znaki w ASCII, ANSI i UTF-8.

Jeśli potrzebujesz znaków spoza zestawu ASCII, musisz wybrać kodowanie. Możesz użyć ANSI, ale potem napotkasz problemy wszystkich różnych stron kodowych. Utwórz plik na komputerze A i przeczytaj go na komputerze B może / będzie produkować zabawnie wyglądające teksty, jeśli te maszyny są skonfigurowane do korzystania z różnych stron kodowych, proste, ponieważ wartość liczbowa nnn reprezentuje różne znaki na tych stronach kodowych.

To „piekło strony kodowej” jest powodem, dla którego zdefiniowano standard Unicode . UTF-8 to tylko jedno kodowanie tego standardu, jest ich znacznie więcej. Najczęściej stosowany jest UTF-16, ponieważ jest to natywne kodowanie dla systemu Windows.

Jeśli więc potrzebujesz obsługiwać coś poza 128 znakami zestawu ASCII, radzę korzystać z UTF-8 . W ten sposób nie ma to znaczenia i nie musisz się martwić, z jaką stroną kodową użytkownicy skonfigurowali swoje systemy.

Marjan Venema
źródło
jeśli nie muszę obsługiwać więcej niż 128 znaków, jaka jest zaleta wyboru kodowania ACSII zamiast kodowania UTF8?
Pacerier
Poza ograniczeniem się do tych 128 znaków? Niewiele. UTF-8 został specjalnie zaprojektowany do obsługi ASCII i większości języków zachodnich, które „tylko” potrzebują ANSI. Przekonasz się, że UTF-8 zakoduje tylko stosunkowo niewielką liczbę wyższych znaków ANSI z więcej niż jednym bajtem. Jest powód, dla którego większość stron HTML używa UTF-8 jako domyślnego ...
Marjan Venema
1
@Pacerier, jeśli nie potrzebujesz kodowania powyżej 127, wybranie ASCII może być przydatne, gdy używasz jakiegoś API do kodowania / dekodowania, ponieważ UTF wymaga dodatkowej weryfikacji bitów, aby uznać dodatkowe bajty za ten sam znak, może to wymagać dodatkowego obliczenia zamiast czysty ASCII, który po prostu odczytuje 8 bitów bez weryfikacji. Ale zalecam używanie ASCII tylko wtedy, gdy naprawdę potrzebujesz wysokiego poziomu optymalizacji w dużych (dużych i dużych) obliczeniach i wiesz, co robisz w tej optymalizacji. Jeśli nie, po prostu użyj UTF-8.
Luciano,