Jaka jest różnica między UTF-8 a ISO-8859-1?

Odpowiedzi:

321

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.

Ignacio Vazquez-Abrams
źródło
11
Należy zauważyć, że ASCII obejmuje tylko od 0 do 127. MSB wynosi zawsze 0
Hritik
3
Gdy zdefiniowane są punkty kodowe powyżej 127, system kodowania jest wersją Extended ASCII.
Rohan Bhale
1
@RohanBhale Nie używaj wyrażenia Extended ASCII; spowoduje tylko zamieszanie.
Pan Lister
Ale rozszerzone ascii może być właściwym terminem. Przeczytałem go na wielu zasobach
Rohan Bhale
135

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.

StaxMan
źródło
@mu może moje stwierdzenie było dwuznaczne, ale nie jest niepoprawne - nie mówiłem o zakodowanych sekwencjach bajtów, ale raczej o kodowaniu zestawów znaków; co oznacza, że ​​ISO-8859-1 jest używany do kodowania pierwszych 256 punktów kodowych zestawu znaków Unicode.
StaxMan,
Twoje wyjaśnienie działa na mnie i „dwuznaczne” byłoby lepszym wyborem słów niż „niepoprawne”.
mu jest za krótki
83

UTF

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

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.

Sammitch
źródło
1
+1 za udzielenie odpowiedzi na pytanie, ale wyjście poza to i zaoferowanie informacji o powiązanych kodowaniach. Re: punkty kodowe dla UTF-8, zgodnie z stackoverflow.com/a/38488358/3353984 , UTF-8 obsługuje 2 ^ 21 punktów kodowych. Czy to błąd, czy może potrzebna jest tutaj poprawka?
Tom Loredo,
1
Unicode jest w rzeczywistości 17 płaszczyznami 2 ^ 16 punktów kodowych. 0x00_0000 na 0x1F_FFFF. 17 samolotów może pomieścić 1114112 punktów kodowych. Spośród nich 2048 to surogaty, 66 to znaki niebędące postaciami, a 137 468 jest zarezerwowanych do użytku prywatnego, pozostawiając 974 530 do publicznego przydzielenia. Około 1 miliona. Zobacz, ile znaków może zakodować UTF-8? .
georgeawg,
22
  • 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'
Cyker
źródło
21

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).

Shital Shah
źródło
1
Widziałem, gdzie Umlaut nie jest rzekomo konwertowany za pomocą UTF8. Widzieliśmy przykłady tego i podczas wyszukiwania znaleźliśmy ISO-8859-1 i wydaje się, że działa. Mamy wielu niemieckich naukowców, z którymi współpracujemy.
Aggie Jon z 87 lat
4
Umlaut są reprezentowane jako dwa znaki w utf8. Konwertują dobrze i działają dobrze. Problem pochodzi z programów, które oczekują 1 bajta na znak. Dla tych starszych programów ISO-8859-1 ma umlaut 1-bajtowy.
Erik Aronesty,
3

Z innej perspektywy, pliki, które zarówno kodowanie Unicode, jak i ASCII nie mogą odczytać, ponieważ mają bajt 0xc0 , wydają się być poprawnie odczytane przez iso-8859-1. Zastrzeżenie polega na tym, że plik nie powinien oczywiście zawierać znaków Unicode.

Nikhil VJ
źródło
2

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-1się 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.

Chris Morgan
źródło
Ups! Myślałem, że to napisałem, ale zgubiłem to na nowo. Włożyłem to teraz.
Chris Morgan
0

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.

Alan Jurgensen
źródło
2
Pomocne, ale myślę, że miałeś na myśli 127 zamiast 255 w rozszerzonym ascii 255?
Hydroper
18
Latin-1 lub iso-8859-1 nie jest w 100% kompatybilny do przechowywania w utf8. Jakikolwiek znak Latin-n lub iso-8859-n powyżej 127 nie zostanie przetłumaczony na pojedynczy bajt utf-8. Jednak w przypadku wartości 1-127 zostaną one przetłumaczone dokładnie.
Marlin Pierce
4
Ta odpowiedź jest nieco myląca w użyciu terminu „rozszerzona ascii”, który jest po prostu terminem odnoszącym się do dowolnego kodowania znaków, które nie jest ASCII. UTF-8 i latin-1 są przykładami rozszerzonego kodowania ASCII. Jednak znaki non-ascii Latin-1 (tj. Punkty kodowe powyżej 127) nie mogą być kodowane jako pojedynczy bajt w UTF-8.
rdb