Digitális karakterkódolás

Az előző fejezetben láthattuk, hogy a számok kettes számrendszerbe való átváltása egyszerű feladat akár az ember számára is. Felmerül viszont a kérdés, hogy mi a helyzet a betűkkel? A Neumann-elvek alapján a számítógép minden adatot kettes számrendszerben dolgoz fel. Ebben az esetben valahogy a betűket is egyesek és nullák sorozatává kellene alakítani. Kézenfekvő megoldás, ha minden betűhöz társítunk egy állandó sorszámot, hiszen ezt a sorszámot már könnyen kettes számrendszerbe tudjuk váltani.

Kezdeti megoldások

Az első, kezdetleges technológiák már a 19. században létrejöttek a távíró és a Morse-kód megjelenésével. Ezek viszont még analóg megoldások voltak. A digitális karakterkódolás a számítástechnika fejlődésével együtt a világháborúk idején alakult ki.

ASCII

0 0000000 5 0000101
1 0000001
2 0000010 125 1111101
3 0000011 126 1111110
4 0000100 127 1111111
Pozitív egész számok ábrázolása 7 bites bitsorozattal

Sokféle próbálkozás volt, de az egyik legfontosabb mérföldkő az 1960-as években kifejlesztett ASCII (American Standard Code for Information Interchange) karaktertábla. A kezdetben 7 bites számokkal dolgozó kódolás összesen 128 különböző karakternek tudott sorszámot adni. Ebben a 128 karakterben szerepelt az angol ábécé 26 kicsi és 26 nagy betűje, 10 számjegy, a legfontosabb írásjelek és matematikai jelek valamint néhány úgynevezett vezérlő karakter.

Hogy megértsük, hogy mit jelent a 7 bites kódolás, elevenítsük fel a kombinatorika ismereteinket! A 7 bit 7 darab számjegyet jelent. Mivel kettes számrendszerben gondolkozunk, ezért ezek a számjegyek csak nullák vagy egyesek lehetnek. Mind a 7 számjegy helyére írhatunk egy darab nullát vagy egy darab egyest, tehát összesen hétszer kétféle választási lehetőségünk van. Így 2×2×2×2×2×2×2 = 27 = 128 különböző bitsorozatot tudunk létrehozni. A csupa nullákból álló bitsorozat a 0., a csupa egyesekből álló bitsorozat a 127. karaktert kódolja.

ISO 8859

Hamar egyértelművé vált azonban, hogy ez a 128 karakter nem lesz elég, ezért az ASCII karakterkódolást 8 bites számokra módosították. Így további 128 karaktert tudtak sorszámozni, ami jelentősen kibővítette a lehetőségeket. Több tucat olyan betű került a kódtáblába, ami például a spanyol, német vagy szláv eredetű nyelvekben megtalálható. Emellett újabb írásjelek és gyakran használt szimbólumok is kaptak sorszámot.

Ez azonban még mindig kevésnek bizonyult, ezért az 1980-as években létrehozták az ISO 8859, más néven Latin kódtáblákat. Ezek az ASCII-hez hasonlóan 8 bites sorszámokat használtak. Az első 128 karakter megegyezett a 7 bites ASCII kódtáblával, a második 128 karakter pedig egy-egy nyelvi régió betűit tartalmazta. Így született meg például a Latin-2 kódtábla, ami a magyar nyelv összes betűjét tartalmazta, vagy a Latin-5, Latin-6 és Latin-7 kódtáblák, amikben a ciril, arab és görög betűk is szerepeltek.

Ugyanakkor az ISO 8859 kódtáblákon kívül még számtalan másikat is létrehoztak az évek során, és ez igen komoly problémához vezetett. Ha ugyanaz a sorszám a különböző kódtáblákban különböző karaktereket jelöl, akkor biztosítani kell, hogy a szöveget ugyanazzal karakterkódolással olvassuk, mint amivel írták. A fájlok fejlécében ugyan meg lehet adni a szöveg karakterkódolását, de ez sok esetben hiányzott. A 2000-es évek elején, az internetelérés rohamos terjedésével ez a probléma ráadásul csak fokozódott. Nem volt ritka, hogy egy szövegben kérdőjelek, üres téglalapok vagy éppen másfajta karakterek jelentek meg az eredeti karakterek helyén. Klasszikus példa volt erre 219. karakter, ami a Latin-2 kódtáblában az Ű, a Latin-1 kódtáblában viszont az Û betűt jelenti.

Külön problémát jelentett, hogy a távolkeleti nyelvek ábécéi egyenként több ezer karaktert tartalmaznak, amiket 8 biten, 256 helyen nem lehet sorszámozni. Ennek megoldására újabb, nyolcnál több bittes kódtáblákat vezettek be, ami tovább bonyolította a helyzetet.

Unicode

A helyhiány és a rengeteg különböző kódtábla problémáira végül a Unicode (univerzális kódolás) nevű karakterkódolás jelentette a megoldást. A szabvány első verziója még az 1990-es évek elején jelent meg, de az igazi áttörés csak a 2000-es évek közepén következett be. Mára viszont szinte egyeduralkodóvá vált, hiszen a legtöbb szövegszerkesztő program alapértelmezetten a Unicode-ot használja.

A régebbi kódtáblák problémáit úgy oldották meg, hogy a 7 és 8 bites sorszámozást 32 bitesre növelték. Ez elméletben ~4,3 milliárd különböző karakter sorszámozására adna lehetőséget, de különböző kompatibilitási és helytakarékossági okokból a gyakorlatban csak ~1,1 millió karakter kezelésére képes. Ez jelentős különbségnek tűnik, viszont a rendelkezésre álló helynek még így is a ~4/5-e üres, ráadásul a későbbiekben a 32 bitet is lehet növelni, ha szükség lesz rá.

A Unicode tartalma

A Unicode jelenleg 139 írásrendszer betűit és írásjeleit támogatja. A latin karakterek mellett a görög, ciril, arab és a távolkeleti nyelvek betűit is tartalmazza. Emelett olyan speciális írásrendszerek karaktereit is használhatjuk, mint például a székely rovásírás, a vakok számára kifejlesztett Braille-írás vagy éppen az egyiptomi hieroglifák.

A Unicode tartalmaz több száz matematikai és tudományos műveletjelet és szimbólumot, és olyan elterjedt szimbólumokat, amiket a mindennapi életben gyakran használunk. Például: különféle nyilak, dobókocka/dominó szimbólumok, hangjegyek, KRESZ táblák, horoszkópok, sakk figurák, pénznemek szimbólumai.

Emojik

Az első emojit 1999-ben rajzolták meg egy japán távközlési cégnél. Kezdetben a szolgáltatók különféle kódolási megoldásokat használtak, és ez az ISO 8859-hez hasonló problémákat okozott. A megoldás végül itt is a Unicode lett. Jelenleg több, mint 2500 emoji rendelkezik 32 bites kóddal.

Az emojik és a fentebb említett hétköznapi szimbólumok között jelentős átfedés van, de az emojik előnye a színes és változó méretű ábrázolás. Éppen ezért olyan szimbólumokat is tartalmaznak (pl.: nemzeti zászlók), amiket a hagyományos karakterekkel nem lehet megfelelően ábrázolni. Ráadásul az emojikat kombinálni is lehet egymással, így könnyedén használhatók a képírás megvalósítására.

UTF-8

A Unicode tehát megoldást jelent a korábbi karakterkódolások két problémájára (a helyhiányra és a különböző karakterek egyforma sorszámozására), de bevezet egy harmadik problémát, a pazarlást. Azok a karakterek, amik eddig 8 biten voltak sorszámozva, már 32 bites sorszámot kapnak, ami azt jelenti, hogy egy szöveges állomány mérete a négyszeresére növekedne. Ez még a mai technológia mellett is pazarlás, ezért egy olyan módszert dolgoztak ki, ami nemcsak az állományok méretét csökkenti, hanem a 7 bites ASCII kódtáblával is teljesen kompatibilis.

1. byte 2. byte 3. byte 4. byte
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Az UTF-8 karakterkódolási algoritmusa

Az UTF-8 egy olyan algoritmus, ami egy egyszerű trükkel, különféle kezdőbit-sorozatok használatával biztosítja, hogy minden Unicode karaktert a lehető legkevesebb byte-on tudjunk ábrázolni. A felesleges 0-kat elhagyva így jelentős mennyiségű tárhelyet tudunk megspórolni.

  • Ha egy byte 0-val kezdődik, az azt jelenti, hogy a soron következő karakter sorszámát egy byte-on is le tudjuk írni. Ilyenkor a program a kezdő 0-t figyelmen kívül hagyja, és csak a maradék hét bitet értelmezi. Az így előállítható bitsorozatok pedig teljes egészében megegyeznek a 7 bites ASCII kódtáblában használt sorszámokkal.
  • Ha egy byte 11-el kezdődik, akkor a soron következő karakter sorszámát csak egynél több byte-on tudjuk leírni. Az 1-esek száma jelöli, hogy hány byte-ra van szükségünk. Ez azért is hasznos, mert ha a bitsorozat valamilyen tárolási vagy hálózati probléma miatt megsérül, akkor csak a sérült karakter esik ki, mert a program könnyen megtalálja a következő karakter sorszámának kezdetét.
  • Ha egy byte 10-val kezdődik, akkor az aktuális byte az előző byte folytatása, együtt alkotják a karakter sorszámát.

Példa

  • Vegyük példának a következő bitsorozatot:
    0101001101101101011010010110110001100101011110010011101000100000111000101001100010111010
  • Osszuk fel 8 bites szakaszokra:
    01010011 01101101 01101001 01101100 01100101 01111001 00111010 00100000 11100010 10011000 10111010
  • Vizsgáljuk az első szakaszt! Mivel 0-val kezdődik, a maradék hét bit önmagában kódol egy karaktert. 1010011(2) = 83(10), vagyis az első szakasz a 83. karaktert, a nagy S betűt kódolja.
  • Ugyanilyen logikával megállapíthatjuk, hogy a következő hét szakasz rendre a kis m, i, l, e és y betűket, valamint a kettőspontot és a szóközt kódolja.
  • A kilencedik szakasz 11-el kezdődik. Az első 0 előtt három darab 1-est találunk, ami azt jelenti, hogy a kilencedik szakaszt is beleszámolva, három szakasz együtt kódolja a következő karaktert. A kilencedik szakasz elején az 1110 bitsorozatot, a tizedik és tizenegyedik szakasz elején az 10 bitsorozatot kell figyelmen kívül hagyni. Az így kapott maradék bitsorozat a következő: 0010011000111010(2) = 9786(10). Ez a karakter pedig nem más, mint a klasszikus smiley: ☺
  • Az első pontban felírt bitsorozat tehát a "Smiley: ☺" karaktersorozatot kódolja.
  • Maga a bitsorozat pedig így néz ki a számítógép szemével:
    0101001101101101011010010110110001100101011110010011101000100000111000101001100010111010