Kāds no http://journal.bad.lv lietotājiem mani palūdza izskaidrot atšķirību starp UTF-8, UTF-16 un Unicodi. Šeit arī skaidrojums, kas varētu noderēt ne tikai viņam.
Reiz kaut kad sen Laacz bija iemetis linku uz jauku rakstu par Unicodi – to var lasīt Joel Spolsky rakstā. Bet ja nu gadījumā nav laika lasīt angliskus tekstus, šeit neliels satura atstāstījums.
Būtībā Unicode ir tikai standarts, kas definē abstraktu kodējumu valodas simboliem, katram simbolam piekārtojot savu kodu. Unicode pasaka, ka “a” == “U+0061”, “ā”=”U+0101” un tamlīdzīgi, bet nav runas par to, kā to nokodēt bitu virknēs.
UTF-16 ir tieša Unicode implementācija – ja ir pateikts, ka a=U0061, tad a kodējam to ar 16 bitiem, tas ir, diviem baitiem – 00 un 61, kas atbilst 003D heksadecimālajā sistēmā.
Unicode apzīmējumus var apskatīt programmā Character Map (Start->Programs->Accessories->System tools->Character map). Tur arī var pamanīt, ka visiem “normālajiem” Ascii burtiem pirmais baits ir vienmēr 00, bet, piemēram, latviešu simboliem pirmajam baitam ir nenulles vērtība (01).
Nez kāpēc amerikāņu un angļu programmētājiem sāka šķist, ka Unicode pamatīga liekvārdība — kāpēc gan viņiem starp katriem diviem baitiem būtu jāraksta 00???? – jo tiešām, viņiem Unicode ne ar ko citu neatšķiras no ASCII.
Tāpēc tika izdomāts UTF-8 kodējums, kuram, ja pirmais baits ir 00, tas tiek izlaists. Līdz ar to priekš “plain ASCII” valodām kā angļu (vai …. hmmm, vai ir vēl kāda?) UTF-8 ir praktiski vienbaitīgs. Toties tekstos, kuri satur arī reģionālos kodējumos nepieciešamos burtus, ik pa brīdim būs “vairāk nekā vienbaitīgi” simboli, tas ir, piemēram, latviešu burtu apzīmēšanai tiek lietoti vismaz divi baiti.
Patiesībā gan UTF-8 rada daudz problēmu. Piemēram, par journal.bad.lv aptaujām zināms, ka atbildes garums drīkst būt ne vairāk kā 255 simboli. Tomēr patiesībā ar to ir domāti 255 baiti, nevis simboli. Tātad, ja tu raksti ar latviešu burtiem, daži no tiem aizņems nevis vienu, bet vairākus baitus, līdz ar to kopējais teksta garums būs mazāks nekā 255 simboli.
Līdzīgi arī problēmas rodas ar tādu vienkāršu uzdevumu kā teksta garuma noskaidrošana – līdz šim varēja paskatīties, cik vietas atmiņā aizņem string tipa mainīgais, tagad ir katru reizi jāpārbauda, vai tajā gadījumā nav vairākbaitīgu simbolu. Arī string tipa vērtību sakārtošana augošā vai dilstošā secībā kļuvusi sarežģītāka – atmiņas apgabalā var būt biti, kas nav jāievēro, salīdzinot divus mainīgos.
Patiesībā priekš mums ērtāks būtu UTF-16 kodējums – salīdzināšana darbotos, garuma noteikšanas funkcijas darbotos, tikai rezultāts būtu jādala ar 2. Vienīgā problēma – tas aizņem tieši divreiz vairāk diska vietas, divreiz vairāk atmiņas un rada divreiz lielāku datu plūsmu, kad nepieciešams pārsūtīt informāciju.
Paldies sm par papildinājumu: UTF-8 var būt vienbaitīgs, bet var arī aizņemt līdz pat sešiem baitiem uz simbolu