Jaka jest różnica między UTF-8 a Unicode?

503

Słyszałem sprzeczne opinie od ludzi - zgodnie ze stroną Wikipedii UTF-8 .

Oni są tym samym, prawda? Czy ktoś może to wyjaśnić?

sarsnake
źródło
1
To, co pisze WIKI o Unicode i UTF, jest moim zdaniem w porządku. Niektóre komentarze na ten temat są dziwne: „W UTF-8 (lub innym kodowaniu wielobajtowym) możliwe jest dzielenie lub obcinanie łańcucha w środku znaku, co może skutkować nieprawidłowym łańcuchem”. Zatem ciąg, który jest kodowany w UTF-8, nie jest już ciągiem, ale tablicą bajtów lub strumieniem bajtów. Znaki tworzące ciąg są kodowane. Oczywiście można go również zdekodować. Teraz oczywiście możesz wyciąć sekwencję utf-8 po bajcie startowym lub po bajcie następnym, ale dlaczego ktoś miałby to zrobić?
wspaniały
Ten artykuł o typach danych ciągów ma charakter edukacyjny: mortoray.com/2013/11/27/the-string-type-is-broken - czasami podczas pracy z ciągami i ich komponentami na poziomie bajtów możesz przypadkowo przeciąć znak na pół .
Everett,

Odpowiedzi:

495

Aby rozwinąć odpowiedzi udzielone przez innych:

Mamy wiele języków z wieloma znakami, które komputery powinny idealnie wyświetlać. Unicode przypisuje każdemu znakowi unikalny numer lub punkt kodowy.

Komputery radzą sobie z takimi liczbami jak bajty ... pomijając tutaj trochę historii i ignorując problemy z pamięcią, komputery 8-bitowe traktowałyby 8-bitowy bajt jako największą jednostkę liczbową łatwo reprezentowaną na sprzęcie, komputery 16-bitowe rozwijałyby się do dwóch bajtów i tak dalej.

Stare kodowania znaków, takie jak ASCII, pochodzą z ery (wcześniejszej) 8-bitów i próbują wcisnąć dominujący język obliczeniowy w tym czasie, tj. Angielski, w liczby od 0 do 127 (7 bitów). Z 26 literami w alfabecie, zarówno w formie wielkiej, jak i dużej, cyfr i znaków interpunkcyjnych, które działały całkiem dobrze. ASCII został rozszerzony o 8 bit dla innych języków innych niż angielski, ale dodatkowe 128 cyfr / punktów kodowych udostępnionych przez to rozszerzenie będzie mapowane na różne znaki w zależności od wyświetlanego języka. Normy ISO-8859 są najczęstszymi formami tego mapowania; ISO-8859-1 i ISO-8859-15 (znany również jako ISO-Latin-1, latin1 i tak, istnieją również dwie różne wersje normy ISO 8859).

Ale to nie wystarczy, jeśli chcesz reprezentować znaki z więcej niż jednego języka, więc wtłoczenie wszystkich dostępnych znaków w jednym bajcie po prostu nie zadziała.

Istnieją zasadniczo dwa różne typy kodowania: jeden rozszerza zakres wartości przez dodanie większej liczby bitów. Przykładami takich kodowań mogą być UCS2 (2 bajty = 16 bitów) i UCS4 (4 bajty = 32 bity). Mają z natury ten sam problem, co normy ASCII i ISO-8859, ponieważ ich zakres wartości jest nadal ograniczony, nawet jeśli limit jest znacznie wyższy.

Drugi typ kodowania wykorzystuje zmienną liczbę bajtów na znak, a najbardziej znanymi kodowaniami do tego są kodowania UTF. Wszystkie kodowania UTF działają mniej więcej w ten sam sposób: wybierasz rozmiar jednostki, który dla UTF-8 wynosi 8 bitów, dla UTF-16 16 bitów, a dla UTF-32 32 bitów. Standard definiuje następnie kilka z tych bitów jako flagi: jeśli są ustawione, to następną jednostkę w sekwencji jednostek należy uznać za część tego samego znaku. Jeśli nie są ustawione, ta jednostka w pełni reprezentuje jedną postać. Zatem najbardziej popularne (angielskie) znaki zajmują tylko jeden bajt w UTF-8 (dwa w UTF-16, 4 w UTF-32), ale inne znaki języka mogą zajmować sześć lub więcej bajtów.

Kodowania wielobajtowe (powinienem powiedzieć, że wiele jednostek po powyższym wyjaśnieniu) mają tę zaletę, że zajmują stosunkowo mało miejsca, ale wadą jest to, że operacje takie jak wyszukiwanie podciągów, porównań itp. Wszystkie muszą dekodować znaki do kodu Unicode punkty, zanim takie operacje będą mogły zostać wykonane (istnieją jednak pewne skróty).

Zarówno standardy UCS, jak i UTF kodują punkty kodowe zdefiniowane w Unicode. Teoretycznie kodowania te mogą być użyte do kodowania dowolnej liczby (w zakresie obsługiwanym przez kodowanie) - ale oczywiście kodowania te zostały stworzone do kodowania punktów kodowych Unicode. I to jest twój związek między nimi.

Windows obsługuje tak zwane ciągi „Unicode” jako ciągi UTF-16, podczas gdy większość UNIXów obecnie domyślnie używa UTF-8. Protokoły komunikacyjne, takie jak HTTP, zwykle działają najlepiej z UTF-8, ponieważ rozmiar jednostki w UTF-8 jest taki sam jak w ASCII, a większość takich protokołów została zaprojektowana w erze ASCII. Z drugiej strony, UTF-16 zapewnia najlepszą średnią wydajność przestrzeni / przetwarzania, reprezentując wszystkie żywe języki.

Standard Unicode definiuje mniej punktów kodowych, niż można przedstawić w 32 bitach. Tak więc dla wszystkich praktycznych celów UTF-32 i UCS4 stały się tym samym kodowaniem, ponieważ prawdopodobnie nie będziesz musiał radzić sobie ze znakami wieloczęściowymi w UTF-32.

Mam nadzieję, że wypełniają niektóre szczegóły.

Scott Tesler
źródło
9
Koncepcyjnie, UCS-2 i UCS-4 to zestawy znaków , a nie kodowanie znaków (stąd nazwa).
Ślimak mechaniczny
74
@Tuukka Błędy w tym poście to legion. Istnieją więcej niż 2 wersje ISO 8859. ASCII nie działało w języku angielskim, brakowało takich rzeczy, jak nawiasy kwadratowe, znaki centa, akcenty i wiele więcej - Unicode nie dotyczy tylko języka innego niż angielski; Angielski też tego potrzebuje !! Żadne punkty kodowe nie zajmują więcej niż 4 bajty w ŻADNYM kodowaniu; ten 6-bajtowy biznes jest całkowicie błędny. Nie można zakodować w UTF żadnej wartości skalarnej Unicode, ponieważ to mówi: surogaty i 66 innych non-postaci są zabronione. UCS-4 i UTF-32 to nie to samo. Nie ma wieloczęściowego UTF-32. UTF-16 nie jest tak wydajny, jak udają - & c & c & c!
tchrist
1
ASCII również nie zawiera znaku funta £ i oczywiście nie zawiera znaku euro € (który jest znacznie młodszy niż ASCII).
TRiG
1
@tchrist Wygląda, że 6 bajtów nie nieprawdopodobne po wszystkim. Zobacz: joelonsoftware.com/articles/Unicode.html, co oznacza, że ​​istnieje znak od 0x04000000do 0x7FFFFFFF, lub w postaci binarnej 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - i to rzeczywiście 6 bajtów. Jednak 6 bajtów JEST maksimum , a nie jak w artykule myląco stwierdza się „sześć bajtów lub więcej ”.
syntaxerror
12
@syntaxerror: „Tylko punkty kodu 128 i wyższe są przechowywane przy użyciu 2, 3, w rzeczywistości do 6 bajtów.” było dokładne, gdy zostało napisane, ale później tego samego roku (dwanaście lat temu) zostało unieważnione. en.wikipedia.org/wiki/UTF-8 mówi: „Oryginalna specyfikacja obejmowała liczby do 31 bitów (pierwotny limit uniwersalnego zestawu znaków). W listopadzie 2003 UTF-8 został ograniczony przez RFC 3629 do końca w U + 10FFFF, aby dopasować ograniczenia kodowania znaków UTF-16. Usunęło to wszystkie 5- i 6-bajtowe sekwencje oraz około połowy sekwencji 4-bajtowych. ”
Mooing Duck
237

Pozwól mi użyć przykładu do zilustrowania tego tematu:

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001

Jak dotąd nic magicznego, to bardzo proste. Powiedzmy, że postanowiliśmy przechowywać tę postać na naszym dysku twardym. Aby to zrobić, musimy przechowywać znak w formacie binarnym. Możemy po prostu przechowywać go tak jak „01101100 01001001”. Gotowy!

Ale poczekaj chwilę, czy „01101100 01001001” to jeden znak lub dwa znaki? Wiedziałeś, że to jedna postać, ponieważ ci mówiłem, ale kiedy komputer ją czyta, nie ma pojęcia. Potrzebujemy więc pewnego rodzaju „kodowania”, aby komputer traktował to jako jedno.

Właśnie tutaj wchodzą zasady „UTF-8”: http://www.fileformat.info/info/unicode/utf8.htm

Binary format of bytes in sequence

1st Byte    2nd Byte    3rd Byte    4th Byte    Number of Free Bits   Maximum Expressible Unicode Value
0xxxxxxx                                                7             007F hex (127)
110xxxxx    10xxxxxx                                (5+6)=11          07FF hex (2047)
1110xxxx    10xxxxxx    10xxxxxx                  (4+6+6)=16          FFFF hex (65535)
11110xxx    10xxxxxx    10xxxxxx    10xxxxxx    (3+6+6+6)=21          10FFFF hex (1,114,111)

Zgodnie z powyższą tabelą, jeśli chcemy przechowywać ten znak w formacie „UTF-8”, musimy poprzedzić nasz znak pewnymi „nagłówkami”. Nasz chiński znak ma długość 16 bitów (sam policz wartość binarną), więc użyjemy formatu w wierszu 3, ponieważ zapewnia on wystarczającą ilość miejsca:

Header  Place holder    Fill in our Binary   Result         
1110    xxxx            0110                 11100110
10      xxxxxx          110001               10110001
10      xxxxxx          001001               10001001

Zapisywanie wyniku w jednym wierszu:

11100110 10110001 10001001

Jest to wartość UTF-8 (binarna) chińskiego znaku! (potwierdź to sam: http://www.fileformat.info/info/unicode/char/6c49/index.htm )

Podsumowanie

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001
embed 6C49 as UTF-8:      11100110 10110001 10001001

PS Jeśli chcesz nauczyć się tego tematu w Pythonie, kliknij tutaj

Cheng
źródło
6
„Ale poczekaj chwilę, czy„ 01101100 01001001 ”to jeden znak lub dwa znaki? Wiedziałeś, że to jeden znak, ponieważ ci mówiłem, ale kiedy komputer go czyta, nie ma pojęcia. Potrzebujemy więc pewnego rodzaju„ kodowania ”, aby powiedz komputerowi, aby traktował to jako jeden ”. No dobrze, ale komputer wciąż nie wie, że powinien go zakodować za pomocą utf-8?
Koray Tugay
15
@KorayTugay Komputer nie wie, jakiego kodowania powinien użyć. Musisz to powiedzieć, kiedy zapisujesz znak w pliku, a także kiedy czytasz znak z pliku.
Cheng
3
@ Connector Komputer nie wie, jakiego formatu użyć. Podczas zapisywania dokumentu edytor tekstu musi jawnie ustawić kodowanie na utf-8 lub inny format, którego użytkownik chce użyć. Ponadto, gdy program do edycji tekstu odczytuje plik, musi wybrać schemat kodowania tekstu, aby poprawnie go zdekodować. To samo dzieje się podczas pisania i wprowadzania litery, edytor tekstu musi wiedzieć, jakiego schematu używasz, aby zapisać go poprawnie.
Cheng
2
Jak interpretowane są te nagłówki? jeśli spojrzę na pierwszą tabelę, to myślę: jeśli bajt zaczyna się od bitu, 0znak jest reprezentowany przez 1 bit (bieżący), jeśli bajt zaczyna się od, 110to znak jest reprezentowany przez 2 bajty (bieżący i następny ( pozostałe bity po 10)), jeśli bajt zaczyna się od, 1110to znak jest reprezentowany przez 3 bajty, bieżące i kolejne 2 bajty (pozostałe bity po 10).
JBoy,
2
Przeczytaj 10 artykułów na temat UTF-8; po przeczytaniu tego zrozumiałem w ciągu 10 sekund :)
jrhee17
201

„Unicode” jest niestety używany na różne sposoby, w zależności od kontekstu. Jego najbardziej poprawne użycie (IMO) jest jako kodowany zestaw znaków - tj. Zestaw znaków i odwzorowanie między znakami a reprezentującymi je punktami kodu liczb całkowitych .

UTF-8 to kodowanie znaków - sposób konwersji z sekwencji bajtów na sekwencje znaków i odwrotnie. Obejmuje cały zestaw znaków Unicode. ASCII jest kodowany jako jeden bajt na znak, a inne znaki zajmują więcej bajtów w zależności od ich dokładnego punktu kodowego (do 4 bajtów dla wszystkich obecnie zdefiniowanych punktów kodowych, tj. Do U-0010FFFF, a nawet 4 bajty mogłyby poradzić sobie z maksymalnie U-001FFFFF).

Kiedy „Unicode” jest używany jako nazwa kodowania znaków (np. Jako właściwość .NET Encoding.Unicode ), zwykle oznacza UTF-16 , który koduje najczęściej używane znaki jako dwa bajty. Niektóre platformy (zwłaszcza .NET i Java) używają UTF-16 jako „natywnego” kodowania znaków. Prowadzi to do włochatych problemów, jeśli musisz się martwić o postacie, których nie można zakodować w pojedynczej wartości UTF-16 (są one zakodowane jako „pary zastępcze”) - ale większość programistów nigdy się tym nie martwi, IME.

Niektóre odniesienia do Unicode:

Jon Skeet
źródło
16
Myślę, że UTF-16 równa się tylko „Unicode” na platformach Windows. Ludzie zwykle używają UTF-8 domyślnie na * nix. +1, dobra odpowiedź
jalf
10
@Chris: Nie, ISO-8859-1 nie jest UTF-8. UTF-8 koduje U + 0080 do U + 00FF jako dwa bajty, a nie jeden. Windows 1252 i ISO-8859-1 są w większości takie same, ale jeśli dobrze pamiętam, różnią się między wartościami 0x80 i 0x99, gdzie ISO 8859-1 ma „dziurę”, ale CP1252 definiuje znaki.
Jon Skeet
13
Pomysł nazywania UTF-16 „Unicode” jest dla mnie niespokojny ze względu na jego potencjał do pomylenia - mimo że wyraźnie wskazano to jedynie jako konwencję .NET. UTF-16 jest sposobem reprezentowania Unicode, ale nie jest to „Kodowanie Unicode”.
thomasrutter
6
@unwesen: UTF-8 nie potrzebuje par zastępczych. Po prostu reprezentuje znaki inne niż BMP, wykorzystując stopniowo dłuższe sekwencje bajtów.
Jon Skeet
5
@RoyiNamir: Tak, „Unicode” jest niestety często używany w znaczeniu „UTF-16”, szczególnie w systemie Windows.
Jon Skeet
108

To nie to samo - UTF-8 to szczególny sposób kodowania Unicode.

Istnieje wiele różnych kodowań, które możesz wybrać w zależności od aplikacji i danych, których zamierzasz użyć. O ile wiem, najczęstsze to UTF-8, UTF-16 i UTF-32.

Greg
źródło
10
Chodzi jednak o to, że niektórzy redaktorzy proponują zapisanie pliku jako „Unicode” LUB „UTF-8”. Zatem wzmianka o tym „Unicode” w tym przypadku to UTF-16, które uważam za konieczne.
serhio
71

Unicode definiuje tylko punkty kodowe , czyli liczbę reprezentującą znak. Sposób przechowywania tych punktów kodu w pamięci zależy od używanego kodowania . UTF-8 to jeden ze sposobów kodowania znaków Unicode, między innymi.

Martin Cote
źródło
2
Chodzi jednak o to, że niektórzy redaktorzy proponują zapisanie pliku jako „Unicode” LUB „UTF-8”. Zatem wzmianka o tym „Unicode” w tym przypadku to UTF-16, które uważam za konieczne.
serhio
Liczba, która przedstawia znak, również wykonuje ASCII.
wspaniały
6
przeczytaj to przed i po zapoznaniu się z resztą odpowiedzi na tej stronie
Dodgie
33

Unicode jest standardem, który określa, wraz z ISO / IEC 10646, Universal Character Set (UCS) który jest nadzbiorem wszystkich istniejących znaków wymaganych do reprezentowania praktycznie wszystkich znanych języków.

Unicode przypisuje Nazwę i Numer ( Kod Znaku lub Punkt Kodowy) ) każdemu znakowi w swoim repertuarze.

Kodowanie UTF-8 to sposób na cyfrową reprezentację tych znaków w pamięci komputera. UTF-8 mapuje każdy punkt kodowy na sekwencję oktetów (8-bitowych bajtów)

Na przykład

Znak UCS = Znak Han Unicode

Kod-punkt UCS = U + 24B62

Kodowanie UTF-8 = F0 A4 AD A2 (hex) = 11110000 10100100 10101101 10100010 (bin)

nocne trasy
źródło
Nie, UTF-8 mapuje tylko punkty kodowe w sekwencji większej niż 127. Wszystko od 0 do 127 nie jest sekwencją, ale pojedynczym bajtem. Btw, ASCII przypisuje także nazwę znaku do liczby, więc jest to to samo, co robi Unicode. Ale Unicode nie zatrzymuje się na punkcie kodowym 127, ale idzie do 0x10ffff.
wspaniały
2
@ jasno ja się różnią. Znaki ascii są rzeczywiście odwzorowane na sekwencję jednobajtową. Pierwszy bit, czyli 0 w przypadku kodu znaków ascii, wskazuje, ile bajtów następuje - zero. http://www.wikiwand.com/en/UTF-8#/DescriptionSpójrz na pierwszy rząd.
nightlytrails
Cóż, dla mnie sekwencja składa się z więcej niż jednego bajtu. Znak ASCII w UTF-8 jest pojedynczym bajtem, przy czym najbardziej znaczący bit jest ustawiony na 0. Punkty kodowe wyższe niż 127 potrzebują następnie sekwencji, które zawsze mają bajt początkowy i jeden, dwa lub trzy kolejne bajty. Dlaczego więc nazwałbyś pojedynczy bajt „sekwencją”?
brighty
Cóż ... Wiele razy prawnicy anglojęzyczni mogą się niepokoić o celowe niewłaściwe użycie oprogramowania. Tutaj jest tak samo. Możesz się o to kłócić. Ale to nie wyjaśni tego.
nightlytrails
1
@brighty Hmmm, W matematyce ciąg 0 elementów jest OK. Sekwencja 1 elementu również tutaj jest w porządku.
chux - Przywróć Monikę
24

Unicode jest tylko standardem, który definiuje zestaw znaków ( UCS ) i kodowanie ( UTF ) do kodowania tego zestawu znaków. Ogólnie jednak Unicode odnosi się do zestawu znaków, a nie do standardu.

Przeczytaj absolutne minimum Każdy programista absolutnie, pozytywnie musi wiedzieć o Unicode i zestawach znaków (bez wymówek!) I Unicode w 5 minut .

Gumbo
źródło
1
@serhio: Wiem. Chociaż istnieją trzy różne kodowania UTF-16: Dwa jawne UTF-16LE i UTF-16BE oraz niejawne UTF-16, w których endianowość jest określona za pomocą BOM.
Gumbo
@Gumbo: Brak BOM nie oznacza, że ​​jest to inne kodowanie. Są tylko dwa kodowania.
Mooing Duck
Powyższy blog został napisany przez CEO Stakcoverflow.
Shailesh Pratapwar
23

Istniejące odpowiedzi już wyjaśniają wiele szczegółów, ale oto bardzo krótka odpowiedź z najbardziej bezpośrednim wyjaśnieniem i przykładem.

Unicode to standard mapujący znaki na punkty kodowe.
Każdy znak ma unikalny punkt kodowy (numer identyfikacyjny), który jest liczbą podobną do 9731.

UTF-8 to kodowania z codepoints.
Aby zapisać wszystkie znaki na dysku (w pliku), UTF-8 dzieli znaki na maksymalnie 4 oktety (sekwencje 8-bitowe) - bajty. UTF-8 jest jednym z kilku kodowań (metod reprezentowania danych). Na przykład w Unicode punkt dziesiętny (97) reprezentuje bałwana (), który składa się z 3 bajtów w UTF-8:E2 98 83

Tutaj jest posortowana lista z losowymi przykładami .

podstawowy 6
źródło
1
Nie! UTF-8 to dobry sposób na kodowanie znaków Unicode, ale możemy kodować również w UTF-16 lub UTF-32. Z UTF-32 mamy relację 1: 1 między DWORD a punktem kodowym, z UTF-16 mamy relację 1: 1 między WORD i punktem kodowym tylko dla punktów kodowych BMP, z wyłączeniem zastępczych i BOM. W UTF-8 mamy relację 1: 1 między bajtem a
punktem kodowym
5
@brighty: Racja, ale dlaczego „Nie!”? Napisałem „UTF-8 jest jednym z kilku kodowań”, ponieważ istnieją również UTF-16 i UTF-32.
basic6
16

1. Unicode

Na całym świecie jest wiele znaków, takich jak „$, &, h, a, t,?, 张, 1, =, + ...”.

Potem przychodzi organizacja, która jest dedykowana tym postaciom,

Stworzyli standard o nazwie „Unicode”.

Standard wygląda następująco:

  • utwórz formularz, w którym każda pozycja nosi nazwę „punktu kodowego” lub „pozycji kodowej”.
  • Całe pozycje są od U + 0000 do U + 10FFFF;
  • Do tej pory niektóre pozycje były wypełnione postaciami, a inne pozycje były zapisywane lub puste.
  • Na przykład pozycja „U + 0024” jest wypełniona znakiem „$”.

PS: Oczywiście istnieje inna organizacja o nazwie ISO utrzymująca inny standard - „ISO 10646” - prawie taki sam.

2. UTF-8

Jak wyżej, U + 0024 jest tylko pozycją, więc nie możemy zapisać „U + 0024” na komputerze dla postaci „$”.

Musi istnieć metoda kodowania.

Potem są metody kodowania, takie jak UTF-8, UTF-16, UTF-32, UCS-2 ....

Zgodnie z UTF-8 punkt kodowy „U + 0024” jest zakodowany w 00100100.

00100100 to wartość, którą zapisujemy na komputerze dla „$”.

wengeezhang
źródło
1
Ogólnie rzecz biorąc, UTF-8 jest jedynym wariantem, z którego korzysta dziś każdy.
Rick James
2
ISO 10646 jest identycznym standardem jak zestaw znaków Unicode. Unicode definiuje wiele rzeczy innych niż zestaw znaków, takich jak reguły sortowania, wielkości liter itp. ISO 10646 jest tylko zestawem znaków (których jest obecnie ponad 130 000). Konsorcjum Unicode i ISO wspólnie opracowują Unicode, przy czym ISO dotyczy tylko zestawu znaków i jego kodowania, a Unicode definiuje także właściwości znaków i reguły przetwarzania tekstu.
thomasrutter
12

Sprawdziłem linki w odpowiedzi Gumbo i chciałem wkleić tutaj część tych rzeczy, aby istniały również na Stack Overflow.

„... Niektórzy ludzie mają błędne przekonanie, że Unicode jest po prostu 16-bitowym kodem, w którym każdy znak zajmuje 16 bitów, a zatem istnieje 65 536 możliwych znaków. To nie jest poprawne. To jeden z najpopularniejszych mitów o Unicode , więc jeśli tak pomyślałeś, nie czuj się źle.

W rzeczywistości Unicode ma inny sposób myślenia o postaciach i musisz zrozumieć sposób myślenia o Unicode, inaczej nic nie będzie miało sensu.

Do tej pory zakładaliśmy, że litera odwzorowuje niektóre bity, które można przechowywać na dysku lub w pamięci:

A -> 0100 0001

W Unicode litera odwzorowuje coś, co nazywa się punktem kodowym, co wciąż jest tylko teoretyczną koncepcją. Sposób reprezentowania tego punktu kodowego w pamięci lub na dysku to zupełnie inna historia ... ”

„... Każda litera platoniczna w każdym alfabecie ma przypisaną magiczną liczbę przez konsorcjum Unicode, która jest zapisana w następujący sposób: U + 0639. Ta magiczna liczba jest nazywana punktem kodowym. U + oznacza„ Unicode ”, a liczby są szesnastkowe. U + 0639 to arabska litera Ain. Angielska litera A to U + 0041 .... ”

„... OK, więc powiedzmy, że mamy ciąg:

Witaj

co w Unicode odpowiada pięciu punktom kodowym:

U + 0048 U + 0065 U + 006C U + 006C U + 006F.

Po prostu kilka punktów kodowych. Naprawdę liczby. Nie powiedzieliśmy jeszcze nic o tym, jak przechowywać to w pamięci lub reprezentować w wiadomości e-mail ... ”

„... Tam właśnie wchodzą kodowania.

Najwcześniejszym pomysłem na kodowanie Unicode, który doprowadził do mitu o dwóch bajtach, było, hej, po prostu przechowujmy te liczby w dwóch bajtach każdy. więc Witam staje

00 48 00 65 00 6C 00 6C 00 6F

Dobrze? Nie tak szybko! Czy nie może to być również:

48 00 65 00 6C 00 6C 00 6F 00? ... ”

kommradHomer
źródło
W ASCII litera jest odwzorowywana również na kod, nie tylko w Unicode.
wspaniały
8

UTF-8 to jeden z możliwych schematów kodowania tekstu Unicode .

Unicode jest o szerokim zakresie, który definiuje ponad 130 000 znaków i przydziela każdemu kod numeryczny (punkt kodowy). Definiuje także zasady sortowania tego tekstu, normalizacji, zmiany wielkości liter i nie tylko. Znak w Unicode jest reprezentowany przez punkt kodowy od zera do 0x10FFFF włącznie, chociaż niektóre punkty kodowe są zastrzeżone i nie można ich używać w przypadku znaków.

Istnieje więcej niż jeden sposób, aby ciąg punktów kodu Unicode można zakodować w strumieniu binarnym. Są to tak zwane „kodowania”. Najprostszym kodowaniem jest UTF-32 , który po prostu przechowuje każdy punkt kodowy jako 32-bitową liczbę całkowitą, każdy o szerokości 4 bajtów.

UTF-8 to kolejne kodowanie, które staje się de facto standardem ze względu na szereg zalet w stosunku do UTF-32 i innych. UTF-8 koduje jako sekwencję wartości jednobajtowych. Każdy punkt kodowy może używać zmiennej liczby tych wartości bajtów. Punkty kodowe w zakresie ASCII są zakodowane bez kodowania, aby były zgodne z ASCII. Punkty kodowe poza tym zakresem używają zmiennej liczby bajtów, 2, 3 lub 4, w zależności od zakresu, w którym się znajdują.

UTF-8 został zaprojektowany z myślą o tych właściwościach:

  • Znaki ASCII są kodowane dokładnie tak, jak w ASCII, tak że ciąg ASCII jest również prawidłowym ciągiem UTF-8.

  • Sortowanie binarne: Sortowanie ciągów UTF-8 za pomocą naiwnego sortowania binarnego nadal spowoduje sortowanie wszystkich punktów kodowych w kolejności numerycznej.

  • Znaki wymagające wielu bajtów nie zawierają żadnych wartości bajtów w zakresie ASCII, dzięki czemu części z nich nie można pomylić ze znakami ASCII. Jest to również funkcja bezpieczeństwa.

  • UTF-8 można łatwo zweryfikować i odróżnić od innych kodowań znaków za pomocą walidatora. Tekst w innych kodowaniach 8-bitowych lub wielobajtowych bardzo rzadko będzie również sprawdzany jako UTF-8.

  • Dostęp losowy: w dowolnym momencie ciągu UTF-8 można stwierdzić, czy bajt w tej pozycji jest pierwszym bajtem znaku, czy nie, i znaleźć początek następnego lub bieżącego znaku, bez potrzeby skanowania do przodu lub wstecz więcej niż kilka bajtów lub przeczytaj cokolwiek na początku strumienia.

thomasrutter
źródło
Kilka drobnych punktów: [1] Czy „Znaki ASCII nie są kodowane dokładnie tak, jak w ASCII ”, nie należy zmieniać na „Znaki ASCII są kodowane dokładnie tak, jak w UTF-8 ? [2] Fraza „Kody w Unicode ...” jest dla mnie niejasna. Masz na myśli „punkty kodu Unicode ...” ?
skomisa,
@skomisa dla punktu 1, miałem na myśli, że kodowanie znaków w zakresie ASCII jest identyczne dla ASCII i UTF-8.
thomasrutter,
Jeśli chodzi o punkt 2, to jest słuszna kwestia i
zredaguję
2

Oni są tym samym, prawda?

Nie są.


Myślę, że pierwsze zdanie na stronie Wikipedii, do której się odnosiłeś, zawiera miłe, krótkie streszczenie:

UTF-8 jest kodowaniem znaków o zmiennej szerokości, zdolnym do kodowania wszystkich 1 112 064 prawidłowych punktów kodowych w Unicode przy użyciu jednego do czterech 8-bitowych bajtów.

Opracować:

  • Unicode jest standardem, który definiuje mapę od znaków do liczb, tak zwane punkty kodowe (jak w poniższym przykładzie). Aby uzyskać pełne mapowanie, możesz zajrzeć tutaj .

    ! -> U+0021 (21),  
    " -> U+0022 (22),  
    \# -> U+0023 (23)
    
  • UTF-8 jest jednym ze sposobów kodowania tych punktów kodowych w formie zrozumiałej dla komputera, czyli bitów . Innymi słowy, jest to sposób / algorytm do konwersji każdego z tych punktów kodowych na sekwencję bitów lub konwersji sekwencji bitów na równoważne punkty kodowe. Zauważ, że istnieje wiele alternatywnych kodowań dla Unicode.


Joel daje naprawdę ładne wyjaśnienie i przegląd historii tutaj .

Dimos
źródło
2

Jeśli mogę streścić to, co zebrałem z tego wątku:

Unicode „tłumaczy” znaki na liczby porządkowe (w postaci dziesiętnej) .

à = 224

UTF-8 to kodowanie, które „tłumaczy” te liczby na reprezentacje binarne .

224 = 11000011 10100000

Zauważ, że mówimy o reprezentacji binarnej 224, a nie jej postaci binarnej, czyli 0b11100000.

Raimi bin Karim
źródło
2

W tym artykule wyjaśniono wszystkie szczegóły http://kunststube.net/encoding/

PISANIE DO BUFORA

jeśli napiszesz do 4-bajtowego bufora, symbolu z kodowaniem UTF8, twój plik binarny będzie wyglądał następująco:

00000000 11100011 10000001 10000010

jeśli napiszesz do 4-bajtowego bufora, symbolu z kodowaniem UTF16, twój plik binarny będzie wyglądał następująco:

00000000 00000000 00110000 01000010

Jak widać, w zależności od tego, jakiego języka użyjesz w swoich treściach, wpłynie to odpowiednio na twoją pamięć.

np. dla tego konkretnego symbolu: kodowanie UTF16 jest bardziej wydajne, ponieważ mamy 2 zapasowe bajty do wykorzystania dla następnego symbolu. Ale to nie znaczy, że musisz używać UTF16 dla japońskiego alfabetu.

CZYTANIE Z BUFORA

Teraz, jeśli chcesz przeczytać powyższe bajty, musisz wiedzieć, w jakim kodowaniu zostało zapisane, i poprawnie je odkodować.

np. jeśli zdekodujesz to: 00000000 11100011 10000001 10000010 do kodowania UTF16, skończysz na nie

Uwaga: Kodowanie i Unicode to dwie różne rzeczy. Unicode to duży (tabela) z każdym symbolem odwzorowanym na unikalny punkt kodowy. na przykład symbol (litera) ma (punkt kodowy) : 30 42 (szesnastkowy). Z drugiej strony kodowanie jest algorytmem, który konwertuje symbole na bardziej odpowiedni sposób, gdy są przechowywane na sprzęcie.

30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.

30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.

wprowadź opis zdjęcia tutaj

InGeek
źródło
bardzo dobry powiązany artykuł, mam nadzieję, że nadal będzie aktywny
yolob 21
0

UTF-8 to metoda kodowania znaków Unicode przy użyciu sekwencji 8-bitowych.

Unicode to standard reprezentujący dużą różnorodność znaków z wielu języków.

akaMahesh
źródło
4
„Sekwencje 8-bitowe”…? Może chcę to sprecyzować…
deceze