Jaka jest różnica między UTF-8 a ISO-8859-1 ?
Jaka jest różnica między UTF-8 a ISO-8859-1 ?
Odpowiedzi:
UTF-8 to kodowanie wielobajtowe, które może reprezentować dowolny znak Unicode. ISO 8859-1 to kodowanie jednobajtowe, które może reprezentować pierwsze 256 znaków Unicode. Oba kodują ASCII dokładnie w ten sam sposób.
Wikipedia wyjaśnia oba dość dobrze: UTF-8 vs Latin-1 (ISO-8859-1). Wcześniejsze jest kodowanie o zmiennej długości, a następnie jednobajtowe kodowanie o stałej długości. Latin-1 koduje tylko pierwsze 256 punktów kodowych zestawu znaków Unicode, natomiast UTF-8 może być używany do kodowania wszystkich punktów kodowych. Na poziomie kodowania fizycznego tylko punkty kodowe 0–127 są kodowane identycznie; punkty kodowe 128 - 255 różnią się tym, że stają się sekwencją 2-bajtową z UTF-8, podczas gdy są to pojedyncze bajty z Latin-1.
UTF to rodzina wielobajtowych schematów kodowania, które mogą reprezentować punkty kodu Unicode, które mogą reprezentować do 2 ^ 31 [około 2 miliardów] znaków. UTF-8 to elastyczny system kodowania, który wykorzystuje od 1 do 4 bajtów do przedstawienia pierwszych 2 ^ 21 [około 2 milionów] punktów kodowych.
Krótko mówiąc: każdy znak o reprezentacji punktu kodowego / porządkowej poniżej 127, czyli 7-bitowy ASCII, jest reprezentowany przez tę samą sekwencję 1-bajtową, jak większość innych kodowań jednobajtowych. Każdy znak o kodzie powyżej 127 jest reprezentowany przez sekwencję dwóch lub więcej bajtów, przy czym najlepiej wyjaśniono tutaj szczegóły kodowania .
ISO-8859 to rodzina schematów kodowania jednobajtowego używanych do reprezentowania alfabetów, które mogą być reprezentowane w zakresie od 127 do 255. Te różne alfabety są zdefiniowane jako „części” w formacie ISO-8859- n , najbardziej znanym z są to prawdopodobnie ISO-8859-1 aka „Latin-1”. Podobnie jak w przypadku UTF-8, 7-bitowy ASCII pozostaje niezmieniony, niezależnie od zastosowanej rodziny kodowania.
Wadą tego schematu kodowania jest jego niezdolność do dostosowania języków składających się z ponad 128 symboli lub bezpiecznego wyświetlania więcej niż jednej rodziny symboli jednocześnie. Również kodowanie ISO-8859 nie sprzyjało wzrostowi liczby UTF. „Grupa robocza” ISO odpowiedzialna za to, że rozwiązała się w 2004 r., Pozostawiając utrzymanie podkomitetowi.
ASCII: 7 bitów. 128 punktów kodowych.
ISO-8859-1: 8 bitów. 256 punktów kodowych.
UTF-8: 8-32 bitów (1-4 bajty). 1 112 064 punktów kodowych.
Zarówno ISO-8859-1, jak i UTF-8 są wstecznie kompatybilne z ASCII, ale UTF-8 nie jest wstecznie kompatybilny z ISO-8859-1:
#!/usr/bin/env python3
c = chr(0xa9)
print(c)
print(c.encode('utf-8'))
print(c.encode('iso-8859-1'))
Wynik:
©
b'\xc2\xa9'
b'\xa9'
ISO-8859-1 to starsze standardy z lat 80. Może reprezentować tylko 256 znaków, więc nadaje się tylko dla niektórych języków w świecie zachodnim. Nawet w wielu obsługiwanych językach brakuje niektórych znaków. Jeśli utworzysz plik tekstowy w tym kodowaniu i spróbujesz skopiować / wkleić niektóre chińskie znaki, zobaczysz dziwne wyniki. Innymi słowy, nie używaj go. Unicode przejęło świat, a UTF-8 jest obecnie standardem, chyba że masz jakieś starsze powody (takie jak nagłówki HTTP, które muszą być kompatybilne ze wszystkim).
Jeszcze jedna ważna rzecz do zrealizowania: jeśli widzisz iso-8859-1
, prawdopodobnie odnosi się to raczej do Windows-1252 niż do ISO / IEC 8859-1 . Różnią się one w zakresie 0x80–0x9F, gdzie ISO 8859-1 ma kody sterujące C1, a Windows-1252 ma użyteczne widoczne znaki.
Na przykład ISO 8859-1 ma 0x85 jako znak kontrolny (w Unicode, U + 0085, ``), podczas gdy Windows-1252 ma poziomą elipsę (w Unicode, U + 2026 HORIZONTAL ELLIPSIS, …
).
WHATWG Kodowanie Spec (jak wykorzystywane przez HTML) oświadcza iso-8859-1
się etykietawindows-1252
i przeglądarek internetowych nie obsługuje ISO 8859-1 w dowolny sposób: spec HTML mówi, że wszystkie kodowania w specyfikacji kodowania muszą być wspierane, a nie więcej .
Co ciekawe, odwołania do znaków numerycznych HTML zasadniczo używają Windows-1252 dla wartości 8-bitowych zamiast punktów kodu Unicode; według https://html.spec.whatwg.org/#numeric-character-reference-end-state , …
wygeneruje U + 2026 zamiast U + 0085.
Moim powodem zbadania tego pytania było z perspektywy, w jaki sposób są one kompatybilne. Zestaw znaków Latin1 (iso-8859) jest w 100% kompatybilny do przechowywania w magazynie danych utf8. Wszystkie znaki ascii i rozszerzone ascii będą przechowywane jako jednobajtowe.
Idąc w drugą stronę, od utf8 do zestawu znaków Latin1 może, ale nie musi działać. Jeśli są jakieś 2-bajtowe znaki (znaki poza rozszerzonym ascii 255), nie będą one przechowywane w magazynie danych Latin1.