Kodowanie to przetwarzanie informacji na pewien kod (nie koniecznie oznacza to szyfrowanie danych). W odróżnieniu od szyfrowania w kryptografii nie chodzi uniemożliwienie przeczytania komunikatu. Wręcz celem jest ujednolicenie stosowanego systemu, aby móc poprawnie wyświetlać strony internetowe w różnych językach w każdym miejscu na świecie. Omówimy tu podstawowe systemy kodowania, takie jak ASCII oraz Unicode.
System znaków ASCII
ASCII to skrót od American Standard Code for Information Interchange. Znaki ASCII kodowane są na 7 bitach, co daje 128 różnych kombinacji od 0 do 127. Zawiera tylko podstawowe znaki alfabetu łacińskiego, cyfry, znaki interpunkcyjne oraz specjalne jak znaki białe, znak null.
Litery małe i duże zapisywane są osobnym kodem. Dodatkowo w różnych językach występują specjalne znaki diakrytyczne, co sprawia, że zestaw znaków ASCII jest niewystarczający. Próba zwiększenia kodowania do 8 bitów czyli podwojenie dostępnych znaków do 256 kombinacji okazała się niewystarczająca. Odpowiedzią na rosnące zapotrzebowanie ujednolicenia systemu kodowania jest Unicode.
Unicode
Unicode dzieli się na kilka różnych systemów. Przykładem jest UTF-8, który stosuje się do kodowania w nim stron internetowych oraz plików. Cechą tego Unicode jest całkowita zgodność ze standardem ASCII. Jest to pierwszy bajt tego systemu.
Bardziej zaawansowane znaki jak np. polskie znaki są potrzebuje już dwóch bajtach. Z tego względu SMS, który zawiera polskie znaki może pomieścić połowę mniej znaków niż zawierający jedynie te mieszczące się na 1 bajcie.
Najbardziej jednak interesuje nas to, że znaki w Javie są kodowane właśnie standardem Unicode.
UTF-8
Zaczynając od znaków kodowanych jednym bajtem mamy do dyspozycji 7 bitów czyli 128 różnych kombinacji. W przypadku słów dwu bajtowych ma do dyspozycji 11 bitów czyli 2048 różnych kombinacji.
W jaki sposób budowane są kody w UTF-8?
Wyobraźmy sobie skład kolejowy, czyli kolejkę i wagony. Z przodu zawsze jedzie kolejka, a potem są wagony.
Zapis słowa jedno-bajtowego
0xxxxxxx – (0 – 0x7F) – W przypadku jedno-bajtowego słowa mamy samą kolejkę. Kodując dane słowo możemy podzielić bajt na dwa ciągi po 4 bity – dzięki temu łatwo zamienić binarny ciąg na zapis szesnastkowy.
1 2 |
0000 0000 to 0x00 0111 1111 to 0x7F |
Zapis słowa dwu-bajtowego
Jeżeli potrzeba więcej bitów niż 7 do zapisania znaków wymagany jest kolejny bajt. Zgodnie z naszą nomenklaturą do kolejki musimy doczepić wagon (czyli kolejny bajt).
110xxxxx 10xxxxxx – (0x80 – 0x7FF)
1 2 |
1100 0000 1000 0000 1101 1111 1011 1111 |
Aby przeczytać powyższe ciągi należy czytać od prawej strony czwórkami i pomijać „stałe” elementy wagonów i kolejki (czyli czytamy tylko znaki, które znajdują się w miejscu x)
Zapis słowa trzy-bajtowego
W przypadku 3 Bajtów będziemy już potrzebować dwóch wagonów.
1110xxxx 10xxxxxx 10xxxxxx – (0x800 – 0xFFFF)
1 2 |
1110 0000 1000 0000 1000 0000 1110 1111 1011 1111 1011 1111 |
Jak widać przy każdym dodatkowym wagoniku (bajcie) do kolejki dodajemy z przodu (najbardziej znaczący bit, najstarszy) 1, a na koniec dopisujemy wagonik w postaci 10xxxxxx.