Różnica między UTF-8 a UTF-16?

Różnica między UTF-8 a UTF-16? Po co nam to?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
Author: Deduplicator, 2011-01-11

4 answers

Uważam, że istnieje wiele dobrych artykułów na ten temat w Internecie, ale tutaj jest krótkie podsumowanie.

Zarówno UTF-8, jak i UTF-16 są kodami o zmiennej długości. Jednak w UTF-8 znak może zajmować minimum 8 bitów, podczas gdy w UTF-16 Długość znaku zaczyna się od 16 bitów.

Główne plusy UTF-8:

  • podstawowe znaki ASCII, takie jak cyfry, znaki łacińskie bez akcentów itp. zajmuje jeden bajt, który jest identyczny z reprezentacją US - ASCII. This way all US-ASCII strings stać się poprawnym UTF-8, który w wielu przypadkach zapewnia przyzwoitą kompatybilność wsteczną.
  • Brak bajtów null, co pozwala na używanie zakończonych null łańcuchów, wprowadza to również dużą kompatybilność wsteczną.
  • UTF - 8 jest niezależny od kolejności bajtów, więc nie musisz się martwić o problem Big Endian / Little Endian.

Główne wady UTF-8:

  • wiele popularnych znaków ma różną długość, co spowalnia indeksowanie przez punkt kodowy i obliczanie liczby punktów kodowych strasznie.
  • chociaż kolejność bajtów nie ma znaczenia, czasami UTF-8 nadal ma BOM (byte order mark), który służy do powiadamiania, że tekst jest zakodowany w UTF-8, a także zrywa kompatybilność z oprogramowaniem ASCII, nawet jeśli Tekst zawiera tylko znaki ASCII. Oprogramowanie firmy Microsoft (takie jak Notatnik) szczególnie lubi dodawać BOM do UTF-8.

Główne zalety UTF-16:

  • BMP (basic multilingual plane) znaki, w tym łacińska, Cyrylica, większość chińska (ChRL wykonała wsparcie dla niektóre Punkty kodowe poza BMP obowiązkowe), większość Japończyków może być reprezentowana za pomocą 2 bajtów. Przyspiesza to indeksowanie i obliczanie liczby punktów kodowych w przypadku, gdy tekst nie zawiera znaków dodatkowych.
  • nawet jeśli tekst ma Dodatkowe znaki, są one nadal reprezentowane przez pary 16-bitowych wartości, co oznacza, że całkowita długość jest nadal podzielna przez dwa i pozwala na użycie 16-bitowego char jako prymitywnego składnika łańcucha.

Główny UTF-16 wady:

  • dużo bajtów null w łańcuchach US-ASCII, co oznacza brak zakończonych null łańcuchów i dużo zmarnowanej pamięci.
  • używanie go jako kodowania o stałej długości "głównie działa" w wielu typowych scenariuszach (szczególnie w USA / UE / krajach z Cyrylicą / Izrael / kraje arabskie / Iran i wiele innych), często prowadząc do przerwania wsparcia tam, gdzie nie ma. oznacza to, że programiści muszą być świadomi par zastępczych i obsługiwać je poprawnie w przypadkach, gdy jest to możliwe. ważne!
  • ma zmienną długość, więc liczenie lub indeksowanie punktów kodowych jest kosztowne, choć mniej niż UTF-8.

Ogólnie rzecz biorąc, UTF-16 jest zwykle lepszy do reprezentacji w pamięci, ponieważ BE/LE nie ma tam znaczenia (wystarczy użyć natywnej kolejności), a indeksowanie jest szybsze (tylko nie zapomnij odpowiednio obsłużyć par zastępczych). Z drugiej strony UTF-8 jest bardzo dobry dla plików tekstowych i protokołów sieciowych, ponieważ nie ma problemu z BE / LE i często przydaje się null-termination, ponieważ oraz zgodność Z ASCII.

 266
Author: Sergei Tachenov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-19 05:23:55

Są to po prostu różne schematy reprezentacji znaków Unicode.

Oba mają zmienną długość-UTF - 16 używa 2 bajtów dla wszystkich znaków w podstawowej płaszczyźnie wielojęzycznej (BMP), która zawiera większość znaków w powszechnym użyciu.

UTF-8 używa od 1 do 3 bajtów dla znaków w BMP, do 4 dla znaków w bieżącym zakresie Unicode od U + 0000 do U+1FFFFF i jest rozszerzalny do U+7FFFFFFF, jeśli zajdzie taka potrzeba... ale przede wszystkim wszystkie znaki ASCII są reprezentowane w jednym bajcie każdy.

Dla celów streszczenia wiadomości nie ma znaczenia, który z nich wybierzesz, o ile każdy, kto spróbuje odtworzyć fragment, używa tej samej opcji.

Zobacz ta strona aby dowiedzieć się więcej o UTF-8 i Unicode.

(zauważ, że wszystkie znaki Javy są kodami UTF-16 w BMP; aby reprezentować znaki powyżej U + FFFF, musisz użyć par zastępczych w Javie.)

 18
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 15:27:03

Jest to niezwiązane z UTF-8/16 (ogólnie rzecz biorąc, chociaż konwertuje na UTF16 i część BE/LE może być ustawiona w/ jednej linii), jednak poniżej znajduje się najszybszy sposób konwersji ciągu znaków na bajt[]. Na przykład: dobre dokładnie dla podanego przypadku (hash code). Sznurek.getBytes (enc) jest stosunkowo wolny.

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }
 3
Author: bestsss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-11 19:29:46

Prosty sposób odróżnienia UTF-8 od UTF-16 polega na określeniu podobieństw między nimi.

Inne niż dzielenie tego samego numeru unicode dla danego znaku, każdy z nich jest własnym formatem.

 0
Author: Venkateswara Rao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 04:59:46