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ć?
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ć?
Odpowiedzi:
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.
0x04000000
do 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 ”.
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 )
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
0
znak jest reprezentowany przez 1 bit (bieżący), jeśli bajt zaczyna się od, 110
to znak jest reprezentowany przez 2 bajty (bieżący i następny ( pozostałe bity po 10
)), jeśli bajt zaczyna się od, 1110
to znak jest reprezentowany przez 3 bajty, bieżące i kolejne 2 bajty (pozostałe bity po 10
).
„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:
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.
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.
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)
http://www.wikiwand.com/en/UTF-8#/Description
Spójrz na pierwszy rząd.
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 .
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 .
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:
PS: Oczywiście istnieje inna organizacja o nazwie ISO utrzymująca inny standard - „ISO 10646” - prawie taki sam.
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 „$”.
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? ... ”
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.
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 .
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.
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.