jaanuar 16, 2016

Sissejuhatus Unikoodi I: terminitest ja munakoksimisest

















Küllaltki pikka aega on patsiga poisid saanud arvutitekstide maailmas läbi vaid ASCII kooditabelit teades. Lisandusid veel täpitähtede tõttu ASCII kooditabeli 2. poole erivariandid ja sellega kogu “lihttekstidega” / “plain text” tegelemine piirdus.
Ja “kõrgemat” järku (mitte siis liht-) tekstidega tegelesid inimesed oma tekstiredaktorite sees ja need tekstid väga sealt välja ei pääsenudki, v.a. trükitööstus.
Lihttekstide sees aga tuli täpitähtede puudumine või mingite saladuslike krakade esinemine nende asemel lihtsalt välja kannatada või kui asi väga hapuks läks, mingi kooditabeli number ümber vahetada (DOS 850 437 asemele, Windows 1252 mingi teise numbri asemel)...
Interneti levik on asja aga muutnud ja tänapäeval ei saa patsiga poiss enam üle ega ümber nähtusest nimega Unikood / Unicode /. Nii otsustasin ka mina märkide kooditabelite vallas mälu värskendada ja see teema läbi uurida (btw, varsti saab Unicode esimene standard 1.0 25 aastaseks, oktoobris 2016 nimelt. ).
Arvutiinimesed on enamasti ka üsna laisad, ja kui lausa ei pea, siis nad midagi vabatahtlikult ka selgeks ei tee. Selle asja peenem nimetus on “lazy evaluation” või sündmuspõhine elukäsitlus. Näiteks ei ole olnud mul kuni viimase ajani vajadust oma auto klaasipesuvedelikku vahetada - talve ju ei olnud saabunud.


Terminite seletamisi ja sissejuhatamisi:

Üritan jätkuvalt kasutada eestikeelseid termineid, kuigi viimane tegevus muutub järjest küsitavamaks. Kõigepealt on vastavad keelereeglid jõudnud luku taha ja saab kasutada vaid avalikult kättesaadavaid räbalaid sellest reeglistusest, teiseks ei tundu vähemalt selle reeglistuse visandites paljusid termineid üldse olemaski olevat. Nii et võtke minu keelekasutust nii nagu see on hetkel välja kukkunud.
Kas see lukustamine häirib mind? Jah, seda sellisel määral, et eelistaks sellel teemal pigem vaikida (aga ei suutnud, nagu selgub). Nagu inglastel poliitika alane vestlus olevat välja kujunenud - ohkas üks ja ohkas teine. Oligi kogu jutuajamine.
Kõik sedalaadi dokumendid peavad olema avalikud ja tasuta kättesaadavad. Raha küsimine oma keele ja kultuuri standardi eest on absurdne ja oma rahva ja keele ja meele säilimisele otseselt vastu toimiv tegevus.

Tähtsaim termin kodeerimises on märk / character / .
See ei ole sama, mis täht /letter /
Tähed on tähestiku / alphabet / (kaas ja täishäälikud ainult ) elemendid.
Märk peaks olema vähim ühik või üksus, millest saab rääkida kodeerimisel. Aga alati ei ole. Nii teeb Unikood vahet atomaarsete märkide (atomic characters) ja liitmärkide (composite characters) vahel.
Märk peaks omama mingit semantilist tähendust. unicode.org definitsiooni järgi.
Märgil võiks olla mingi graafiline tähistus olemas, kui ta pole juhtumisi kontrollmärk...
Aga siin oleme jälle probleemi ees, sest seesama A võib olla esitatud 1001 erineval viisil.
Neid erinevaid graafilisi esitusi nimetatakse glüüfideks (glyph).
Näide - kaldkirjas või rasvaselt või mingil erilisel viisil trükitud A ...

Oletame nüüd, et oleme välja valinud mingi hulga märke.
Saadud hulka (ilma lisaelementideta, nagu näiteks märgi kood...) nimetame märgivalikuks / character repertoire /.

Jätan targu täpsemalt märkimata, et see märgivalik peaks olema mingis mõttes täielik (morsetähestik koos kirjavahemärkidega näiteks), siis on sellega kui tervikhulgaga mõtet üldse tegelda.

Märgistik / character set / === märgivalik + lisaks muud elemendid, mis on vajalikud märgistiku funktsioneerimise jaoks.
Näiteks morsemärgistikus on vajalik teada veel igale märgile vastavate punktide ja kriipsude jada ehk kodeeringut.
Näide:
... --- ...” peaks tähendama SOS signaali.
Arvutiinimeste jaoks ei oma mingi ebamäärane märgistik mingit tähendust enne, kui me ei jõua märkide juurest arvude juurde.
Kuid stop siin - me ei jõua järgmises punktis veel mitte bittide ja baitide juurde, vaid ainult arvudeni.

Kodeeritud märgistik / coded character set / on selline märgistik, kus igale märgile on omistatud arvkood (ka null).
Enamasti märgistik === kodeeritud märgistik.

Märgi koodipunkt / code point /on kodeeritud märgistikus märgile vastav arv.
Unikoodi koodipunkti tähistatakse nii: U+xxxxx, kus xxxxx on hex arv, mis seda koodinumbrit esitab. Nulli arvu ees ei kirjutata, kui arvu pikkus on > 4 hex märki.
U+0020 tähistab näiteks tühiku märki.

Kodeeritud märgistiku kõige tähtsam näide ongi muidugi
Unikood / Unicode / UTF .

Märgistiku kodeerimisskeem / character encoding scheme / on viis, kuidas märgistiku märkide koodipunkte (arve) esitatakse bittide jadana.
Kuigi Unikood tähistab ühte (ja ainult ühte) märgistikku koos ühe (ja ainult ühe) kodeeringuga,
omab Unikood 7 -t erinevat viisi või kodeerimisskeemi oma märkide baitideks ümberpanekul.
(bittidega tegelemine on pigem teoreetiline harrastus, praktiliselt tegeldakse alati baitidega).
Neid nimetatakse nii:
UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE.
UTF - Unicode Transformation Format - Unikoodi teisendusformaat.
Number ütleb ära infobittide arvu, ühes info- või koodiühikus, BE, LE juurde veel jõuame.
Koodiühik enamasti võib tähistada ühte märki (ja “enamasti” võiks tõsi olla just seetõttu, et kettaruumi kokku hoida).
Aga kui ei saa ühe koodiühikuga hakkama, kasutatakse mitut. Unikood on muutuva pikkusega kodeeritud märgistik utf-8 ja utf-16 variantide (veel ka kodeerimisvormide) puhul.

Need on asjad, mille üle peate mõtlema. Vanal heal ajal oli sageli kehtiv seos, et üks bait tähistas ühte tähte (ASCII ja tema laiendid). Tõsi, et teada saada, mis tähte see bait esitas, oli vajalik sageli teada, mis koodileheküljest jutt käis ja kui seda ei teadnud, siis oli/on tulemiks abakadabra. Teoreetiliselt sai neid koodilehekülgi teksti sees vahetada, aga see ei toiminud eriti hästi.
Arvamus, et Unikoodis kulub ühele märgile 2 baiti, on müüt, millest tuleks otsustavalt loobuda.
utf-8 -s on enamiku teksti puhul ühele märgile kuluv ruum 1 bait. Kui märkideks on aga mitte ASCII tähed (laiendatud ASCII, Hiina, Jaapan etc...), läheb baite rohkem vaja,
utf-16-l enamasti kulub 2 baiti, aga võib kuluda ka 4.
Vaid utf-32 variantides kulub iga märgi kodeeerimiseks 4 baiti.

BE ja LE



jämedaotsaline / big-endian / BE /- baidijärjestus on arvutiarhitektuur või andmevahetusviis, kus arvutisõnas kõige suurema väärtusega bait tuleb enne, kui väiksema väärtusega bait.
Sarnane näide kümnendesitusest: 1728 esituses kõige tähtsam arv, tuhandeliste arv, tuleb kõige enne.
Ka arvuti sees või kõhus võib arvu esitav sõna, mis koosneb mitmest baidist, olla tõlgendatud 2-l erineval moel. Hex arv 0xFF00 võib tähistada arvu 255 või 65280 (255*256).
Arvutivõrkudes andmevahetus toimub (enamasti, äkki on kusagil erandeid?) BE kokkuleppe kohaselt.
peeneotsaline / little-endian / LE / baidijärjests on vastupidine BE-le, kus kõige väiksema väärtusega baidid tulevad enne.

Nüüd peaks olema selge, mida tähistab BE ja LE Unikoodi skeemide nimetustes - see ütleb, mis järjekorras unikoodi ühikule vastavat 2 või 4 baiti tuleks edastada.
utf-8-s sellist asja aga vaja ei ole.
Sellest hoolimata võib kõikide unikoodi edastatavate baitide ette kirjutada spetsiaalse baitide jada nimetusega BOM (Byte Order Mark, baidijärjestuse märk), mis ütleb ära, mis utf kodeerimisskeemi rakendatakse.
Seda võib teha isegi utf-8 puhul ja seda teeb peamiselt Microsoft (näiteks eraldi teema PowerShelli tekstiväljastuste puhul. Sellest õigupoolest tekkiski soov Unikoodi / UTF teema ükskord klaariks saada).
HTML5 -s enamasti on kasutusel kas UTF-8 või mõni muu vanem koodistik ja piisab html failide päises olevast
märgendist. (või mõni muu kooditabel). 
Aga saab kõige ette kirjutada ka BOM märgid, iseküsimus, kas teie sirvik sellisest leheküljest aru saab.
UTF-8 omapära on see, et muude ühebaidiliste kodeeringute puhul üsna pea tekivad sel juhul utf-8-s keelatud baidijadad ja seetõttu võib üsna kindlasti ilma igasuguse BOM-ta öelda, et asi on kas UTF-8 või ei ole (on näiteks mõni vanem kodeering ISO 8859 perekonnast.)
Nii võib tegelikult väita, et BOM utf-8 puhul on lausa ülearune spämm, millest siiski võiks olla abi eraldamiseks ennast võimalikest vanadest kodeeringutest. Aga ei ole, sest ülejäänud mitteMS maailm ei kasuta utf-8 puhul enamasti BOM-i!


BE ja LE mõistete päritolust



Jonathan Swift kirjutas kunagi raamatu Gulliveri reisidest. Gulliver käis ära Lilliputi keisririigis ja lõpetas oma seikluse Lilliputiga konkureerivas Blefuscu keisririigis.
Nende riikide vahel käis Gulliveri visiidi ajal (ja ka enne seda) armutu sõda ja sõja põhjuseks oli erinev keedumunade purukskoksimise viis.
Varemalt peeti Lilliputimaal normaalseks muna purustamise meetodiks munade jämedast otsast katki löömist.
Siis aga vigastas tollase Lilliputi keisri vanaisa poisikesena oma sõrme sel viisil muna koksides ning ...
seejärel keelustati keedetud muna purustamine jämedamast otsast (big-endian / BE method).
Lilliputlased jäid seetõttu peeneotsalise, (LE ehk Little-endian ) meetodi juurde ja blefusculased pidasid paremaks BE meetodit, kuigi üldiselt vist suhtusid teemasse pisut liberaalsemalt.

180 aastat hiljem, nähes sarnast kodusõda, mis arvutiprotsessorite vallas valitseb, kirjutas
Danny Cohen selle kohta sellise artikli:
Terminid “Big-endian” ja “Little-endian” hakkasid arvutiinimestele meeldima ja võeti laialdaselt kasutusele.
Nii on Jonathan Swift koos sõjakate lilliputlaste ja blefusculastega aidanud luua arvutiterminoloogiat.
Ka mina omalt poolt pakun seetõttu koos Heiki Vallastega big-endian ja little-endian
vasteteks jämedaotsaline ja peeneotsaline baidijärjestus
Little-endiani vastet Swifti tekstis ma ei leidnudki, eks see oli Danny Coheni enda lisandus.
Ja nagu ikka konformistina olen mina jämeda otsa (BE poolt). Lõppude lõpuks oleks väga imelik hakata aastaarvu 2016 kirjutama 6102, nagu tagurpidi Antsud seda tahaksid.
Pealekauba sundisid LE-d toetavad lilliputlased Gulliveri põgenema. 1728 lilliputi toidunorm ilmselt jäi sellele mehele ka väheks (Lilliputi teadlased arvutasid välja, et lineaarmõõt erines nende ja Gulliveril 12 korda, siit arv 12*12*12 = 1728 toidukoguse jaoks )
Aga protsessorite maailmas on
BE arhitektuuriga Motorola, Sparc...
LE arhitektuuriga on Intel protsessorid
ARM - arhitektuuri puhul saab seda programselt sättida.
(See on pealiskaudne resümee ja vajaks vastava raua-ala eksperdi täpsustusi.)
Andmevahetuse puhul aga peab olema teadlik et kahebaidiliste koodide vahetamise korral on vaja enne selgeks saada, mis järjekorras mingit märki esitavad 2 baiti on, BE või LE järjestuses.
Vaikimisi eeldatakse siiski BE baidijärjestust.

Sellega panen siin ajutise punkti - kuigi jätan õiguse lisandada mõisteid terminitesse või täiesti ümber kirjutada ühte kui teist, kui vajalik peaks tunduma.

Unikoodi järgmine pajatus peaks kõnetama vaid veel elus olevaid telegraafifänne, sest räägib koodistikest kuni 1963-nda aastani, ühesõnaga Noa ajast enne ASCII-d.