Różnica między UTF-8 i UTF-16? Dlaczego tego potrzebujemy?
MessageDigest md =MessageDigest.getInstance("SHA-256");String text ="This is some text";
md.update(text.getBytes("UTF-8"));// Change this to "UTF-16" if neededbyte[] digest = md.digest();
Wydaje mi się, że w Internecie jest wiele dobrych artykułów na ten temat, ale oto krótkie podsumowanie.
Zarówno UTF-8, jak i UTF-16 to kodowania 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 zalety UTF-8:
Podstawowe znaki ASCII, takie jak cyfry, znaki łacińskie bez akcentów itp., Zajmują jeden bajt, co jest identyczne z reprezentacją US-ASCII. W ten sposób wszystkie łańcuchy US-ASCII stają się poprawnymi kodami UTF-8, co w wielu przypadkach zapewnia przyzwoitą kompatybilność wsteczną.
Brak bajtów zerowych, co pozwala na użycie ciągów zakończonych znakiem null, wprowadza to również dużą część kompatybilności wstecznej.
UTF-8 jest niezależny od kolejności bajtów, więc nie musisz martwić się problemem Big Endian / Little Endian.
Główne wady UTF-8:
Wiele typowych znaków ma różną długość, co strasznie spowalnia indeksowanie według punktu kodowego i obliczanie liczby punktów kodowych.
Mimo że kolejność bajtów nie ma znaczenia, czasami UTF-8 nadal ma BOM (znak kolejności bajtów), który służy do powiadomienia, że tekst jest zakodowany w UTF-8, a także łamie zgodność 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:
Znaki BMP (podstawowa wielojęzyczna płaszczyzna), w tym łaciński, cyrylica, większość chińskich (w ChRL obsługa niektórych punktów kodowych poza BMP jest obowiązkowa), większość japońskiego może być reprezentowana przez 2 bajty. Przyspiesza to indeksowanie i obliczanie liczby punktów kodowych w przypadku, gdy tekst nie zawiera dodatkowych znaków.
Nawet jeśli tekst zawiera znaki uzupełniające, nadal są one reprezentowane przez pary wartości 16-bitowych, co oznacza, że całkowita długość jest nadal podzielna przez dwa i pozwala na użycie 16-bitowego charjako pierwotnego składnika ciągu.
Główne wady UTF-16:
Wiele bajtów zerowych w łańcuchach US-ASCII, co oznacza brak ciągów zakończonych znakiem null i dużo zmarnowanej pamięci.
Używanie go jako kodowania o stałej długości „działa” głównie w wielu typowych scenariuszach (szczególnie w USA / UE / krajach z alfabetem cyrylicy / Izrael / kraje arabskie / Iran i wiele innych), często prowadząc do zerwania wsparcia tam, gdzie tak nie jest. Oznacza to, że programiści muszą być świadomi par zastępczych i odpowiednio je obsługiwać w przypadkach, w których ma to znaczenie!
Ma zmienną długość, więc liczenie lub indeksowanie punktów kodowych jest kosztowne, chociaż 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 (po prostu użyj kolejności natywnej), a indeksowanie jest szybsze (tylko nie zapomnij o prawidłowej obsłudze par zastępczych). Z drugiej strony UTF-8 jest wyjątkowo dobry w przypadku plików tekstowych i protokołów sieciowych, ponieważ nie ma problemu z BE / LE i często przydaje się zakończenie zerowe, a także kompatybilność z ASCII.
Tak, zapomniałem o BE / LE. Nie jest to jednak wielka sprawa, szczególnie w przypadku używania w pamięci. UTF-8 generuje dłuższe dane wyjściowe tylko wtedy, gdy używane są znaki trzy-bajtowe, ale oznacza to głównie chiński i japoński. Z drugiej strony, jeśli tekst zawiera dużo znaków US-ASCII, może generować krótszy wynik, więc to, czy jest to minus, czy nie, zależy od konkretnej sytuacji.
Nawet nie pomyślałem o natychmiastowym pro utf-8, krótszej długości. W przybliżeniu dłuższe wyjście utf-8 było „może” z jakiegoś powodu, ale jeśli cel znajduje się na dalekim wschodzie, domyślne kodowanie powinno być utf-16. Jak na przykład md.update (text.getBytes ("UTF-8")); kodowanie nie ma znaczenia, ponieważ hash jest stabilny w obie strony.
Mówisz, że znaki mają różną długość w UTF-8, więc spowalnia indeksowanie i obliczanie długości, ale wątpię, czy znaki w UTF-16 mają również inną długość, czy indeksowanie i obliczanie długości UTF-16 powinno być szybsze?
Są to po prostu różne schematy reprezentowania znaków Unicode.
Oba mają zmienną długość - UTF-16 wykorzystuje 2 bajty na wszystkie znaki w podstawowej płaszczyźnie wielojęzycznej (BMP), która zawiera większość powszechnie używanych znaków.
UTF-8 wykorzystuje od 1 do 3 bajtów dla znaków w BMP, do 4 dla znaków w obecnym zakresie Unicode od U + 0000 do U + 1FFFFF i można go rozszerzyć do U + 7FFFFFFF, jeśli zajdzie taka potrzeba ... ale przede wszystkim wszystkie znaki ASCII są reprezentowane w jednym bajcie.
Na potrzeby podsumowania wiadomości nie ma znaczenia, który z nich wybierzesz, o ile każdy, kto próbuje odtworzyć podsumowanie, korzysta z tej samej opcji.
Zobacz tę stronę, aby uzyskać więcej informacji na temat UTF-8 i Unicode.
(Zauważ, że wszystkie znaki Java są punktami kodowymi UTF-16 w BMP; aby przedstawić znaki powyżej U + FFFF, musisz użyć par zastępczych w Javie.)
Zarysowane tutaj problemy [bezpieczeństwa] znikają, gdy używa się wyłącznie UTF-8, co jest jednym z wielu powodów, dla których jest teraz obowiązkowe kodowanie wszystkich rzeczy.
Inne grupy mówią to samo.
Tak więc, podczas gdy UTF-16 może nadal być używany wewnętrznie przez niektóre systemy, takie jak Java i Windows, to niewielkie wykorzystanie UTF-16, które mogłeś widzieć w przeszłości do plików danych, wymiany danych itp., Prawdopodobnie zniknie całkowicie.
Nie ma to związku z UTF-8/16 (generalnie, chociaż konwertuje do UTF16, a część BE / LE można ustawić w jednej linii), ale poniżej znajduje się najszybszy sposób konwersji String na bajt []. Na przykład: dobre dokładnie dla podanego przypadku (kod skrótu). String.getBytes (enc) jest stosunkowo powolny.
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.