Microsoft Word - diploma-b.doc

Podobni dokumenti
Turingov stroj in programiranje Barbara Strniša Opis in definicija Definirajmo nekaj oznak: Σ abeceda... končna neprazna množica simbolo

Microsoft Word - avd_vaje_ars1_1.doc

RAM stroj Nataša Naglič 4. junij RAM RAM - random access machine Bralno pisalni, eno akumulatorski računalnik. Sestavljajo ga bralni in pisalni

Diapozitiv 1

Učinkovita izvedba algoritma Goldberg-Tarjan Teja Peklaj 26. februar Definicije Definicija 1 Naj bo (G, u, s, t) omrežje, f : E(G) R, za katero v

Slide 1

6.1 Uvod 6 Igra Chomp Marko Repše, Chomp je nepristranska igra dveh igralcev s popolno informacijo na dvo (ali vec) dimenzionalnem prostoru

Teorija kodiranja in kriptografija 2013/ AES

Urejevalna razdalja Avtorji: Nino Cajnkar, Gregor Kikelj Mentorica: Anja Petković 1 Motivacija Tajnica v posadki MARS - a je pridna delavka, ampak se

Poročilo za 1. del seminarske naloge- igrica Kača Opis igrice Kača (Snake) je klasična igrica, pogosto prednaložena na malce starejših mobilnih telefo

Strojna oprema

Microsoft Word - M docx

Zadeva: Ponudba

Microsoft PowerPoint - RKO6.ppt

Microsoft Word - M docx

Document ID / Revision : 0519/1.3 ID Issuer System (sistem izdajatelja identifikacijskih oznak) Navodila za registracijo gospodarskih subjektov

1 MMK - Spletne tehnologije Vaja 5: Spletni obrazci Vaja 5 : Spletni obrazci 1. Element form Spletni obrazci so namenjeni zbiranju uporabniških podatk

COBISS3/Medknjižnična izposoja

ŠTEVCI PROMETA IN NJIHOVA UPORABA ZA NAMENE STATISTIK ČRT GRAHONJA

Uradni list RS - 12(71)/2005, Mednarodne pogodbe

Delavnica Načrtovanje digitalnih vezij

MATLAB programiranje MATLAB... programski jezik in programersko okolje Zakaj Matlab? tipičen proceduralni jezik enostaven za uporabo hitro učenje prir

Microsoft Word - vaje2_ora.doc

Protokoli v računalniškem komuniciranju TCP, IP, nivojski model, paket informacij.

Microsoft Word - UP_Lekcija04_2014.docx

Priloga 1: Pravila za oblikovanje in uporabo standardiziranih referenc pri opravljanju plačilnih storitev Stran 4012 / Št. 34 / Uradni lis

STAVKI _5_

NEVTRIN d.o.o. Podjetje za razvoj elektronike, Podgorje 42a, 1241 Kamnik, Slovenia Telefon: Faks.: in

Zbornica zdravstvene in babiške nege Slovenije Zveza strokovnih društev medicinskih sester, babic in zdravstvenih tehnikov Slovenije Stanje:

Microsoft PowerPoint - Glasbena teorija 1

Navodila za uporabo Mini prenosna HD kamera s snemalnikom

Vaja 2 Virtualizacija fizičnih strežnikov in virtualni PC A. Strežnik Vmware ESX Namestitev strežnika VMware ESX 3.5 na fizični strežnik 2. Nas

Microsoft Word - CNC obdelava kazalo vsebine.doc

Uvod ABECEDA A a B b C c Č č D d E e F f G g H h I i J j K k L l M m N n O o P p R r S s Š š T t U u V v Z z Ž ž ČRKA GLAS ABECEDA S ZA ZAČETEK ŠTEVIL

Navodila za programsko opremo FeriX Namestitev na trdi disk Avtor navodil: Martin Terbuc Datum: December 2007 Center odprte kode Slovenije Spletna str

Microsoft Word - M docx

GHOSTBUSTERS navodila za učitelje O PROJEKTU S tem projektom se učenci sami naučijo izdelati igro. Ustvariti morajo več ikon (duhcov ali kaj drugega)

Datum in kraj

Vaja 3 Kopiranje VM in namestitev aplikacij - strežnik SQL 2000 SP3a A. Lokalni strežnik Vmware ESX Dodajanje uporabnikov vajexx v skupino Vaje

(Microsoft Word - U\350enje telegrafije po Kochovi metodi.doc)

Kazalo 1 DVOMESTNE RELACIJE Operacije z dvomestnimi relacijami Predstavitev relacij

DZS, d. d. Spoštovani, pred vami je vzorčno poglavje dnevnih priprav. Priprave so uporabnikom na voljo v celoti in v obliki, ki omogoča urejanje in pr

Microsoft Word - SI_vaja1.doc

Navodila za uporabo Mini snemalnik

Procesorski sistemi v telekomunikacijah

Vrste

Ime in priimek: Vpisna št: FAKULTETA ZA MATEMATIKO IN FIZIKO Oddelek za matematiko Verjetnost Pisni izpit 5. februar 2018 Navodila Pazljivo preberite

NAJRAJE SE DRUŽIM S SVIČNIKOM, SAJ LAHKO VADIM ČRTE IN KRIVULJE, PA VELIKE TISKANE ČRKE IN ŠTEVILKE DO 20. Preizkusite znanje vaših otrok in natisnite

Microsoft Word - M doc

Si.mobil Si.most Najkrajša pot do vaših strank. Ljubljana,

DN5(Kor).dvi

Delavnica Načrtovanje digitalnih vezij

DIGITALNE STRUKTURE Zapiski predavanj Branko Šter, Ljubo Pipan 2 Razdeljevalniki Razdeljevalnik (demultipleksor) opravlja funkcijo, ki je obratna funk

Microsoft Word - NAVODILA ZA UPORABO.docx

EU-TPD 1 PODROBNOSTI KODIRANJA Informacije za trgovino JB za DCTA, (Final 1.2) Obveznost kodiranja izdelka, urejena s predpisom EU-TPD se n

Microsoft Word - CN-BTU4 Quick Guide_SI

PRIPOROČILA ZA OBLIKOVANJE KATALOGOV ZNANJA ZA MODULE V PROGRAMIH VIŠJEGA STROKOVNEGA IZOBRAŽEVANJA

UNIVERZA V LJUBLJANI FAKULTETA ZA MATEMATIKO IN FIZIKO Katja Ciglar Analiza občutljivosti v Excel-u Seminarska naloga pri predmetu Optimizacija v fina

Prekinitveni način delovanja PLK Glavni program (OB1; MAIN) se izvaja ciklično Prekinitev začasno ustavi izvajanje glavnega programa in zažene izvajan

Navodila Trgovina iCenter

Elektronska pošta

Microsoft Word - CNR-MPV2 Quick Guide_SI

N

Microsoft Word - CNR-BTU3_Bluetooth_vmesnik

Orodje za izvoz podatkov

rm.dvi

4.Racionalna števila Ulomek je zapis oblike. Sestavljen je iz števila a (a ), ki ga imenujemo števec, in iz števila b (b, b 0), ki ga imenujemo imenov

INFORMATOR BIROKRAT 1/2011

2.1 Osnovni pojmi 2 Nim Ga²per Ko²mrlj, Denicija 2.1 P-poloºaj je poloºaj, ki je izgubljen za igralca na potezi. N- poloºaj je poloºaj, ki

ELEKTRIČNI NIHAJNI KROG TEORIJA Električni nihajni krog je električno vezje, ki služi za generacijo visokofrekvenče izmenične napetosti. V osnovi je "

UPRAVLJANJE RAZPRŠENIH PODATKOV Shranjevanje, zaščita in vzdrževanje informacij, ki jih najbolj potrebujete

NAVODILA ZA IZPOLNJEVANJE OBRAZCA

Vostro 430 Informacijski tehnični list o namestitvi in funkcijah

PowerPointova predstavitev

CelotniPraktikum_2011_verZaTisk.pdf

DES11_realno

Microsoft Word - vprasalnik_AZU2007.doc

Diapozitiv 1

1. izbirni test za MMO 2018 Ljubljana, 16. december Naj bo n naravno število. Na mizi imamo n 2 okraskov n različnih barv in ni nujno, da imam

DES

Optimizacija z roji delcev - Seminarska naloga pri predmetu Izbrana poglavja iz optimizacije

Mladi za napredek Maribora srečanje DOLŽINA»SPIRALE«Matematika Raziskovalna naloga Februar 2015

Diapozitiv 1

Spoznajmo PowerPoint 2013

BYOB Žogica v vesolju Besedilo naloge Glavna ideja igre je paziti, da žoga ne pade na tla igralne površine, pri tem pa zbrati čim več točk. Podobno ig

ANALITIČNA GEOMETRIJA V RAVNINI

FGG14

Osnove matematicne analize 2018/19

Navodila za pripravo oglasov na strani Med.Over.Net v 2.2 Statistično najboljši odziv uporabnikov je na oglase, ki hitro in neposredno prenesejo osnov

'Kombinatoricna optimizacija / Lokalna optimizacija'

Chapter 1

RAČUNALNIŠTVO VARNOSTNA KOPIJA IN SLIKA DISKA Aleš Ovsenek Uvajanje novih izobraževalnih programov v srednjem poklicnem in strokovnem izobraževanju s

Microsoft Word - N _moderacija.docx

Univerza v Ljubljani FAKULTETA ZA RAČUNALNIŠTVO IN INFORMATIKO Tržaška c. 25, 1000 Ljubljana Realizacija n-bitnega polnega seštevalnika z uporabo kvan

Microsoft Word - UNI_Tomc_Edi_1968.doc

Delavnica Načrtovanje digitalnih vezij

PowerPointova predstavitev

Podatkovni model ER

Microsoft PowerPoint - OAPS1- Uvod.ppt

Transkripcija:

UNIVERZA V MARIBORU FAKULTETA ZA ELEKTROTEHNIKO, RAUNALNIŠTVO IN INFORMATIKO Janko HERLAH PRAKTINA UPORABA ALGORITMOV STISKANJA PODATKOV Diplomska naloga Maribor, Julij 009

I UNIVERZA V MARIBORU FAKULTETA ZA ELEKTROTEHNIKO, RAUNALNIŠTVO IN INFORMATIKO 000 Maribor, Smetanova ul. 7 Diplomska naloga univerzitetnega študijskega programa PRAKTINA UPORABA ALGORITMOV STISKANJA PODATKOV Študent: Študijski program: Smer: Janko HERLAH Univerzitetni, raunalništvo in informatika Programska oprema Mentor: red. prof. dr. Borut ŽALIK Maribor, Julij 009

II

III PRAKTINA UPORABA ALGORITMOV STISKANJA PODATKOV Kljune besede: algoritmi, brezizgubno stiskanje podatkov, algoritem Deflate, kode CRC, vmesnik IMAPI UDK: 004.67 (043.) Povzetek V diplomskem delu smo izdelali in opisali aplikacijo za arhiviranje podatkov. Opisali smo algoritme za brezizgubno stiskanje podatkov RLE, LZ77 in Huffmanovo kodiranje, strukturo datoteke ZIP ter algoritem Deflate. Prav tako razložimo teoretine osnove raunanja kode CRC. Za zapisovanje na medije CD/DVD smo uporabili programski vmesnik IMAPI ter opisali njegovo uporabo.

IV PRACTICAL USE OF DATA COMPRESSION ALGORITHMS Keywords: algorithms, lossless data compression, algorithm Deflate, CRC codes, IMAPI interface UDK: 004.67 (043.) Abstract As a result of the diploma thesis, a data archiving program is described. Firstly, a ZIP file structure is explained and some lossless data compression algorithms are presented: RLE, LZ77, Huffman coding and Deflate. Additionally, theoretical principles of CRC arithmetics are introduced. For staging and burning image files to CD/DVD optical media, an IMAPI programming interface is used and a very simplified procedure for CD/DVD burning is provided.

V VSEBINA UVOD... PREDSTAVITEV ALGORITMOV STISKANJA... 5. Algoritem RLE... 5. Algoritem LZ77... 6.3 Huffmanovo kodiranje... 9 3 ALGORITEM DEFLATE... 5 3. Naini kodiranja... 9 3. Dinamine kodne tabele... 3 4 STRUKTURA DATOTEKE ZIP... 8 5 KODA CRC... 34 6 IMAPI... 4 6. Znani problemi... 43 6. Vmesniki IMAPI... 45 7 PROGRAM... 5 7. Razredni diagrami... 5 7. Predstavitev delovanja programa... 57 7.3 Parametri za samodejni zagon... 63 8 ZAKLJUEK... 65 LITERATURA... 67 PRILOGA A: Seznam slik... 68 PRILOGA B: Seznam tabel... 69 PRILOGA C: Vsebina zgošenke... 70

Praktina uporaba algoritmov stiskanja podatkov UVOD V diplomskem delu bomo prikazali praktino uporabo nekaterih algoritmov stiskanja podatkov. V ta namen bomo napisali program, ki bo omogoal arhiviranje. Arhiviranje bo možno izvesti rono ali samodejno ob prej nastavljenem asu. Datoteke bomo kodirali z algoritmom Deflate ([], [], [3] in [4]), rezultat pa zapisali v arhiv ZIP ([5]). Za arhiv ZIP smo se odloili, ker je najbolj razširjen format arhivskih datotek in ga je možno odpreti tudi z drugimi programi. Program bomo nadgradili še z dodatnimi možnostmi kot so: obnovitev podatkov iz arhiva in zapisovanje na medije CD in DVD. Proces stiskanja podatkov pretvarja poljubno vhodno zaporedje znakov v kodirano izhodno zaporedje, ki pa je manjše po velikosti. Ta trditev v splošnem velja, poznamo pa tudi algoritme, ki lahko v posebno neugodnih primerih tvorijo daljše izhodno zaporedje. Takšnemu pojavu pravimo negativno stiskanje in se mu poskušamo izogniti. Omenimo tudi, da ne obstaja algoritem, ki bi vse vrste podatkov stisnil optimalno. Nekateri postopki so boljši za stiskanje slik, drugi za stiskanje besedila, spet tretji za stiskanje zvoka ali videa itd. Uinkovitost algoritma merimo z razmerjem stiskanja. Razmerje stiskanja definiramo kot razmerje med velikostjo kodiranega in originalnega zaporedja. Stiskanje dosežemo, e je razmerje stiskanja manjše od ena. Razmerje stiskanja = velikost izhodnega kodiranega zaporedja velikost vhodnega zaporedja (.) Ko razmišljamo, kako bi imbolj optimalno stisnili podatke, se nam takoj prikrade vprašanje: ali lahko izboljšamo stisljivost že samo s tem, e stisnjene datoteke stisnemo še enkrat? Odgovor je: NE. Stisnjene datoteke imajo ni ali zelo malo odvene informacije, saj je bila odstranjena v prvem postopku stiskanja, zato

Praktina uporaba algoritmov stiskanja podatkov ni ve kaj odvzeti. Lahko pa na vprašanje odgovorimo tudi intuitivno. e bi lahko stiskali že stisnjene datoteke, bi vsak nadaljni postopek stiskanja še dodatno zmanjšal velikost datoteke. Postopek bi ponavljali poljubno dolgo, dokler ne bi na koncu dobili zelo majhno datoteko, npr. dolžine enega zloga (angl. byte). To pa je nesmisel, saj v en zlog ne moremo shraniti informacijo, ki jo vsebuje poljubno dolga datoteka. Kako torej dosežemo stiskanje? Vsako zaporedje znakov, ne glede na to, ali predstavlja sliko, zvok ali kaj drugega, lahko vsebuje odveno informacijo, ki jo imenujemo redundanca. e odveno informacijo odstranimo, dobimo zaporedje, ki je manjše po velikosti. Da dobimo imbolj optimalen rezultat, izhodno zaporedje kodiramo. Simbolom, ki se v zaporedju pojavljajo velikokrat, dodelimo im krajše kode. Simboli, ki se pojavijo redko, lahko imajo daljše kode, ker ne bodo bistveno vplivali na velikost izhodnega niza. Za proces kodiranja potrebujemo kodirnik (angl. encoder), za obratni proces dekodiranja, ki nam iz kodiranega niza vrne original, pa dekodirnik (angl. decoder). Lastnosti obeh so doloene z izbranim algoritmom stiskanja. Podrobna predstavitev nekaterih algoritmov stiskanja bo predstavljena v drugem poglavju. Najprej bomo opisali algoritem RLE (angl. Run-Length Encoding), ki daje dobre rezultate pri ponavljajoih se vrednostih. Kadar se nek znak vhodnega zaporedja ponovi n-krat, v izhodno zaporedje zapišemo en sam znak in njegovo število ponovitev. Sledil bo opis algoritma LZ77 (angl. Sliding Window). Osnovna ideja algoritma je, da del vhodnega niza, ki smo ga že obdelali, uporabimo kot slovar. Ko itamo vhodni niz znak za znakom, poskušamo v slovarju najti enak niz. V izhodni niz zapišemo trojek (odmik od konca slovarja, dolžina ujemanja, znak). Algoritem daje tem boljše rezultate, e uspemo v slovarju najti dolge nize. Na koncu si bomo ogledali še Huffmanovo kodiranje. Huffmanovo kodiranje je zelo priljubljeno, ker generira najbolj optimalne kode simbolom, ki nastopajo najvekrat, dodeljuje najkrajše kode. Slaba stran algoritma je, da zahteva veliko korakov. V prvem koraku ugotovi verjetnosti pojavljanja posameznih simbolov. Nato gradi binarno drevo tako, da v vsakem koraku poiše

Praktina uporaba algoritmov stiskanja podatkov 3 dva simbola A in B z najmanjšo verjetnostjo pojavljanja in ju združi v nov simbol AB. Nov simbol vstavi v seznam, znaka A in B pa odstrani iz seznama. Tako se seznam z vsakim korakom skri za en element. Postopek je konan, ko v seznamu ostane samo en element, ki predstavlja koren Huffmanovega drevesa. Vsako vozliše drevesa prispeva en bit v kodi posameznega simbola. V tretjem poglavju bomo uporabili vse znanje iz drugega poglavja in opisali algoritem Deflate, ki spada v skupino algoritmov brez izgub. Napisal ga je Philip W. Katz. Njegov originalni algoritem je patentno zašiten, vse ostale razliice pa so v javni lasti (angl. public domain). Je splošno namenski algoritem, primeren za stiskanje vseh vrst podatkov, zato ga danes sreamo v mnogih priljubljenih programih, kot so: WinZip in Gzip: programa za arhiviranje podatkov operacijski sistem Windows : od Windows XP dalje se uporablja za arhiviranje (stisnjene mape in datoteke) format Adobe PDF: format za opis dokumentov protokol HTTP: protokol, ki nam omogoa brskanje po internetu format PNG: vrsta zapisa slike Zlib: knjižnica, ki sta jo razvila Jean-Loup Gailly in Mark Adler in jo razvijalci lahko prosto uporabijo v svojih aplikacijah itd. V etrtem poglavju bomo opisali osnovno strukturo datoteke ZIP, zato se ne bomo spušali v vse podrobnosti specifikacije. Želimo dosei zapisovanje v arhiv in branje iz njega. Eden izmed pomembnejših podatkov v arhivu ZIP je koda CRC ([6] in [7]), ki jo moramo priložiti k vsaki stisnjeni datoteki. Služi za odkrivanje napak v arhivu (ali je bila datoteka spremenjena). Ker so datoteke kodirane, lahko že sprememba enega bita povzroi, da datoteke ni možno odkodirati. Generiranje kode CRC bo opisano v petem poglavju. V šestem poglavju bomo opisali programski vmesnik IMAPI (angl. Image Mastering API) in njegovo uporabo. IMAPI ([8]) služi za zapisovanje na medije

Praktina uporaba algoritmov stiskanja podatkov 4 CD/DVD. Od Windows XP dalje je del Microsoftovih operacijskih sistemov. Omogoa zelo natanno kontrolo nad procesom zapisovanja podatkov, saj vsebuje kar osemintrideset vmesnikov (angl. Interface). Opisan bo postopek, kako v program dodamo funkcionalnost, ki jo nudi IMAPI. Opisani bodo tudi najvažnejši vmesniki in njihove metode. V sedmem poglavju bo predstavljena zgradba in delovanje programa. Program omogoa arhiviranje, obnovitev podatkov in zapisovanje na medije CD/DVD. Opisani bodo najvažnejši razredi in metode. Predstavljen bo grafini vmesnik programa, s katerim upravljamo, ko se nahajamo v interaktivnem nainu. Podali bomo tudi opis ukaznih parametrov, s katerimi krmilimo program, ko se izvaja v ozadju, brez posredovanja uporabnika. Zakljuek bomo izkoristili za opis splošnih ugotovitev glede razvoja programa. Nakazane bodo nekatere omejitve in možne rešitve.

Praktina uporaba algoritmov stiskanja podatkov 5 PREDSTAVITEV ALGORITMOV STISKANJA V drugem poglavju bomo pripravili osnovo za opis algoritma Deflate. Predstavljeni bodo trije algoritmi: RLE, LZ77 in Huffmanovo kodiranje. Za boljše razumevanje bomo pri vsakem opisu podali tudi podroben primer.. Algoritem RLE Ideja algoritma je zelo preprosta. Kadar se nek znak vhodnega zaporedja ponovi n-krat, v izhodno zaporedje zapišemo dvojek (število ponovitev, znak). Oklepajev in vejic ne pišemo v izhodni kodirani niz, prikazujemo jih zaradi boljše berljivosti. Edini problem pri takšnem kodiranju je, kako dekodirnik loi med znakom in številom ponovitev. Rešitev je ve, naštejmo jih samo nekaj. Dodajanje posebnega znaka: izberemo katerikoli znak, ki ne nastopa v vhodnem zaporedju in ga zapišemo pred številom ponovitev. Algoritem je neuporaben, e lahko v vhodnem zaporedju priakujemo celoten nabor znakov (noben znak ne moremo»žrtvovati«kot poseben znak). Ker moramo v izhodni niz zapisati trojek (poseben znak, število ponovitev, znak), lahko ta pristop uporabimo samo, e se znak ponovi vsaj trikrat. Primer: kodirajmo vhodno zaporedje AAABCDDDDEEFFFFF. Za poseben znak si izberemo znak @. Dobimo: @3ABC@4DEE@5F. Zaporedje treh enakih znakov: ko kodirnik naleti na zaporedje vsaj treh enakih znakov, v izhodni niz zapiše znak trikrat, ki pa mu takoj sledi preostalo število ponovitev. Slaba stran tega pristopa je, da pri treh enakih znakih dosežemo razširitev, stisljivost pa šele pri petih enakih znakih.

Praktina uporaba algoritmov stiskanja podatkov 6 Primer: kodirajmo vhodno zaporedje AAABCDDDDEEFFFFF.Dobimo: AAA0BCDDDEEFFF. Uporaba kontrolnega zloga: kadar imamo vsaj tri enake zaporedne znake, jih v izhodni niz zapišemo kot dvojek (število ponovitev, znak), pri tem pa v kontrolnem zlogu z ustreznim bitom oznaimo, kje v naslednjih osmih zlogih se nahaja število ponovitev. V izhodni niz najprej zapišemo kontrolni zlog, ki mu sledi osem podatkovnih zlogov, nato sledi kontrolni zlog za naslednjih osem podatkovnih zlogov itd. Na raun kontrolnih zlogov se izhodno zaporedje povea za /8 celotne dolžine. Pri sodobnih raunalnikih lahko ta prirastek zmanjšamo z uporabo 3- bitnih ali 64-bitnih kontrolnih zlogov. Primer: kodirajmo vhodno zaporedje AAABCDDDDEEFFFFF.Dobimo: 000000 3ABC4DEE 0 5F Kontrolni zlog je prikazan kot binarno število. Iz bitov kontrolnega zloga lepo vidimo položaje zlogov, ki oznaujejo število ponovitev.. Algoritem LZ77 Algoritem LZ77 je doživel mnogo sprememb. Številni avtorji so izboljšali posamezne dele algoritma in tako ustvarili celo vrsto razliic kot so: LZX (Jonathan Forbes), LZH (Bernd Herd), LZSS (Storer in Szymanski), LZFG (Edward Fiala in Daniel Greene), LZRW in LZRW4 (Ross Williams), QIC- itd. Mi se bomo osredotoili na osnovno izvedbo algoritma. Vhodni niz znakov, ki jih želimo kodirati, razdelimo na dva dela. Leva stran je slovar (angl. dictionary) in vsebuje znake, ki smo jih že kodirali. Na zaetku kodiranja je slovar prazen. Desna stran predstavlja zaporedje znakov, ki jih še moramo obdelati. Iz desne strani po vrsti jemljemo znake in iz njih tvorimo besedo, ki je najprej dolžine enega znaka, nato dveh, treh itd. Besedo poveujemo z dodajanjem znakov dokler lahko v slovarju najdemo ujemanje. Ko pridemo do besede, ki je ni v slovarju, v izhodno zaporedje namesto besede zapišemo trojek (odmik od konca slovarja, dolžina ujemanja, zadnji znak besede). Oklepajev in vejic ne pišemo v izhodni kodirani niz, prikazujemo jih zaradi berljivosti. Na zaetku, ko je slovar majhen, ne najdemo ujemanja niti za besede dolžine enega znaka, zato moramo v izhodno zaporedje

Praktina uporaba algoritmov stiskanja podatkov 7 zapisati trojek (0, 0, znak). Pravkar obdelano besedo nato pomaknemo na levo stran v slovar. Algoritem daje tem boljše rezultate, e uspemo v slovarju najti dolge besede. Primer: z algoritmom LZ77 kodirajmo stavek»raunalnik rauna «. Na zaetku je slovar prazen. slovar R a u n a l n i k r a u n a... besedilo Slika..: Algoritem LZ77 (prazen slovar) Obdelujemo R, prvo rko besedila. Ker je slovar prazen, v izhodni niz zapišemo (0,0,R), rko R pa prestavimo v slovar. slovar R a u n a l n i k r a u n a... besedilo Slika..: Algoritem LZ77 (prvi korak) Nadaljujemo z a, drugo rko besedila. Ker v slovarju ne najdemo rke a, v izhodni niz zapišemo (0,0,a), rko pa prestavimo v slovar. Podobno velja tudi za naslednje rke:, u, n. Ker v slovarju ne najdemo ujemanja, v izhodni niz zapišemo (0,0,), (0,0,u) in (0,0,n). R a u n a l n i k r a u n a... slovar besedilo Slika..3: Algoritem LZ77 (po nekaj korakih) Sedaj je spet na vrsti rka a, ki se že nahaja v slovarju in sicer na odmiku 4 (slovar preiskujemo od konca proti zaetku). Ker smo našli ujemanje, preberemo naslednjo rko l, da dobimo besedo»al«in pogledamo, ali na odmiku 4 najdemo ujemanje. Na tem mestu nimamo ujemanja, zato si zapomnimo odmik 4 in dolžino ujemanja. Nato celoten postopek ponovimo od odmika 4 dalje. V slovarju poskušamo najti naslednji a. Ker ga ne najdemo, v izhodni niz zapišemo (4,,l),»al«pa prestavimo v slovar.

Praktina uporaba algoritmov stiskanja podatkov 8 R a u n a l n i k r a u n a... slovar besedilo Slika..4: Algoritem LZ77 (nadaljevanje) Tudi rko n najdemo v slovarju, na odmiku 3, zato preberemo naslednjo rko i, da dobimo besedo»ni«. Ponovno preverimo, ali na odmiku 3 najdemo ujemanje za besedo»ni«. Ujemanja ni, zato si zapomnimo odmik 3 in dolžino ujemanja ter poskušamo v slovarju najti še kakšen n. Ker ga ne najdemo, v izhodni niz zapišemo (3,,i),»ni«pa prestavimo v slovar. rke k ni v slovarju, zato jo kodiramo kot (0,0,k). Podobno velja tudi za presledek: (0,0, ) in rko r: (0,0,r). R a u n a l n i k r a u n a... slovar besedilo Slika..5: Algoritem LZ77 (zadnji korak) Prišli smo do rke a, ki jo v slovarju najdemo na odmiku 7. Ker smo našli ujemanje, poveamo besedo na»a«. Na odmiku 7 nimamo ve ujemanja za besedo»a«, zato si zapomnimo odmik 7 in dolžino ujemanja in v slovarju poskušamo najti še kakšen a. Naslednjo rko a najdemo na odmiku. Po vrsti beremo rke u, n, a in za besede»au«,»aun«in»auna«vsaki najdemo ujemanje na odmiku. Na koncu pridemo do besede»auna «, ki pa je ni v slovarju. Ker je dolžina ujemanja daljša od tiste na odmiku 7, v izhodni niz zapišemo (,5, ), besedo»auna «pa dodamo v slovar. Konni izhodni niz se glasi: (0,0,R), (0,0,a), (0,0,), (0,0,u), (0,0,n), (4,,l), (3,,i), (0,0,k), (0,0, ), (0,0,r), (,5, ). Prednost zgornjega pristopa je v tem, da si vedno zapomnimo samo eno, najdaljše ujemanje, s imer privarujemo pri pomnilniku. e se zgodi, da imamo ve ujemanj enake dolžine, v izhodni niz zapišemo tisto, ki smo ga našli nazadnje (ki je najbolj oddaljeno od konca slovarja). Ker moramo vsaki v izhodni niz zapisati trojek (odmik, dolžina, znak), smo na zgornjem kratkem primeru dosegli negativno stiskanje, t.j. izhodni niz je daljši od originala. V praksi pa imamo slovar dolžine nekaj tiso zlogov, zato je velika verjetnost, da bomo v slovarju našli ujemanje daljših besed in tako dosegli boljše razmerje stiskanja. Omenimo še, da

Praktina uporaba algoritmov stiskanja podatkov 9 besedo, ki smo jo nazadnje obdelali, ne selimo fizino po pomnilniku iz desne na levo stran v slovar, temve si pomagamo s kazalcem, ki oznauje konec slovarja. S pomikanjem kazalca v desno selimo besede v slovar. Ko smo obdelali celoten vhodni niz, imamo dve možnosti: preberemo nove podatke in zanemo s praznim slovarjem. S tem bomo na zaetku postopka spet pridelali veliko trojkov (0, 0, znak), kar je slabo za uinkovitost stiskanja. Boljši rezultat dosežemo, e del slovarja pomaknemo po pomnilniku v levo, ustrezno popravimo kazalec na konec slovarja, preostanek pomnilnika pa napolnimo z novimi podatki..3 Huffmanovo kodiranje Je eden najbolj priljubljenih algoritmov za stiskanje podatkov. K priljubljenosti je gotovo prispevalo dejstvo, da ga je enostavno implementirati, kakor tudi, da tvori optimalne kode simbolom, ki se pojavljajo najvekrat, dodeljuje najkrajše kode. V prvem koraku moramo pregledati vhodno zaporedje in ugotoviti, kolikokrat se posamezni simbol pojavlja (v literaturi obiajno navajamo verjetnosti posameznih simbolov, v praksi pa zaradi hitrosti izvajanja rajši operiramo s frekvenco pojavljanja, ki je celo število). Nato tabelo simbolov glede na število pojavljanj uredimo v padajoem vrstnem redu in vsak simbol predstavimo kot vozliše drevesa. Sedaj lahko zanemo graditi binarno drevo. Posebnost Huffmanovega algoritma je, da gradi drevo od spodaj navzgor, t.j. od listov h korenu. Na vsakem koraku izberemo dve vozliši V A in V B z najnižjo frekvenco pojavljanja. Ker je tabela urejena padajoe, nam vozliš ni treba iskati, temve vedno vzamemo zadnji dve. Obe vozliši povežemo v novo delno drevo, katerega levi list je vozliše V A, desni list vozliše V B, koren pa novo vozliše V AB. Frekvenco pojavljanja novega vozliša V AB dobimo tako, da seštejemo frekvenci vozliš V A in V B. Nato vozliši V A in V B odstranimo iz seznama, vozliše V AB pa vstavimo tako, da je seznam še vedno urejen padajoe. Po vsakem koraku se seznam zmanjša za en element. Postopek je konan, ko se število elementov v seznamu skri na ena. Zadnji element predstavlja koren celotnega binarnega drevesa. Kode za posamezni simbol dobimo tako, da obišemo vsa vozliša drevesa. Vsako vozliše prispeva en bit v izhodni kodi simbola. Omenimo, da obstaja tudi razliica

Praktina uporaba algoritmov stiskanja podatkov 0 algoritma, kjer tabele simbolov ne urejamo po padajoem vrstnem redu. V tem primeru moramo na vsakem koraku pregledati celotno tabelo, da najdemo simbola z najnižjo frekvenco pojavljanja. eprav je iskanje bolj zamudno, pa odpade vzdrževanje urejenosti tabele. Primer: s Huffmanovim algoritmom kodirajmo stavek»raunalnik rauna «. Najprej moramo ugotoviti, kolikokrat se posamezni simbol pojavlja. Presledek je predstavljen s simbolom. V R V a V V u V n V l V i V k V V r 4 3 Slika.3.: Huffmanovo kodiranje (prvi korak) Nato seznam uredimo padajoe glede na frekvenco pojavljanja posameznega simbola. Primeren je katerikoli algoritem, ki zna urediti seznam števil, npr. QuickSort. V a V n V V u V V R V l V i V k V r 4 3 Slika.3.: Huffmanovo kodiranje (drugi korak) Zanemo graditi binarno drevo. Izberemo dva simbola z najmanjšo frekvenco pojavljanja: V k in V r ter tvorimo novo vozliše V kr s frekvenco (seštejemo frekvenci simbolov V k in V r ). Vozliši V k in V r odstranimo iz seznama, vozliše V kr pa vstavimo v seznam na šesto mesto tako, da je seznam še vedno urejen padajoe. Dejansko lahko vozliše V kr uvrstimo poljubno na mesta 3, 4, 5 ali 6, pa se optimalnost kode ne bi spremenila. Spremenile bi se samo kode posameznih simbolov. V a V n V V u V V kr V R V l V i 4 3 V k V r Slika.3.3: Huffmanovo kodiranje (tretji korak) V naslednjem koraku zopet izberemo dva simbola z najnižjo frekvenco pojavljanja: V l in V i. Tvorimo

Praktina uporaba algoritmov stiskanja podatkov novo vozliše V li, ki ima spet frekvenco. Simbola V l in V i odstranimo iz seznama, simbol V li pa vstavimo v seznam na sedmem mestu (ker mora biti seznam ves as urejen padajoe glede na frekvenco pojavljanja). V a 4 V n 3 V V u V V kr V li V R V k V r V l V i Slika.3.4: Huffmanovo kodiranje (etrti korak) Postopek ponavljamo in na vsakem koraku izberemo dve vozliši z najnižjo frekvenco, t.j. zadnji dve vozliši v seznamu. Nadaljujemo z izbiro vozliš V li in V R in tvorimo novo vozliše V lir s frekvenco 3. Vozliši V li in V R odstranimo iz seznama, novo vozliše V lir uvrstimo v seznam na tretjem mestu. V a V n V lir V V u V V kr 4 3 3 V li V R V k V r V l V i Slika.3.5: Huffmanovo kodiranje (peti korak) Iz vozliš V in V kr tvorimo vozliše V kr. Vozliši V in V kr odstranimo iz seznama, novo vozliše V kr s frekvenco 4 pa vstavimo v seznam na drugem mestu.

Praktina uporaba algoritmov stiskanja podatkov V a V kr V n V lir V V u 4 4 3 3 V V kr V li V R V k V r V l V i Slika.3.6: Huffmanovo kodiranje (šesti korak) Vozliši V in V u nam data novo vozliše V u s frekvenco 4, ki ga uvrstimo v seznam na tretjem mestu. V a V kr V u V n V lir 4 4 4 3 3 V V kr V V u V li V R V k V r V l V i Slika.3.7: Huffmanovo kodiranje (sedmi korak) Naslednji korak izbere vozliši V n in V lir. Iz njih tvorimo vozliše V nlir s frekvenco 6, ki ga moramo dati v seznam na prvo mesto. V nlir V a V kr V u 6 4 4 4 V n V lir V V kr V V u 3 3 V li V R V k V r V l V i Slika.3.8: Huffmanovo kodiranje (osmi korak)

Praktina uporaba algoritmov stiskanja podatkov 3 V devetem koraku izberemo vozliši V kr in V u. Tvorimo novo vozliše V kru s frekvenco 8, ki ga moramo uvrstiti v seznam na prvo mesto. V kru 8 V nlir 6 V a 4 V kr V u V n V lir 4 4 3 3 V V kr V V u V li V R V k V r V l V i Slika.3.9: Huffmanovo kodiranje (deveti korak) Ostaneta še dva koraka. V prvem izberemo vozliši V nlir in V a. Tvorimo novo vozliše V nlira s frekvenco 0, ki ga moramo dati v seznam na prvo mesto. V nlira 0 V kru 8 V nlir V a V kr V u 6 4 4 4 V n V lir V V kr V V u 3 3 V li V R V k V r V l V i Slika.3.0: Huffmanovo kodiranje (deseti korak) Na koncu sta nam ostali samo dve vozliši V nlira in V kru, ki ju združimo v vozliše V nlirakru s frekvenco 8. Ker se je seznam skril na samo eno vozliše, je postopek konan, vozliše V nlirakru pa predstavlja koren binarnega drevesa.

Praktina uporaba algoritmov stiskanja podatkov 4 V nlira kru 8 V nlira 0 V kru 8 V nlir V a V kr V u 6 4 4 4 V n V lir V V kr V V u 3 3 V li V R V k V r V l V i Slika.3.: Huffmanovo kodiranje (zadnji korak) Da dobimo kode za naš nabor simbolov, moramo obiskati vsa vozliša drevesa. Prehod v vozliše na levi oznaimo z 0, prehod v vozliše na desni pa z. Tako vsako vozliše prispeva en bit v konni kodi simbola. Zapišimo Huffmanove kode za naše simbole: Simbol Koda n 000 l 0000 i 000 R 00 a 0 00 k 00 r 0 0 u Tabela.3.: Huffmanove kode za primer»raunalnik rauna «Iz primera lahko vidimo, da algoritem dodeljuje najkrajše kode ravno tistim simbolom, ki se pojavljajo najvekrat. Pri gradnji drevesa bi lahko simbole izbirali tudi kako drugae. Dokler se držimo naela, da na vsakem koraku izberemo dva simbola z najnižjo frekvenco pojavljanja, ne vplivamo na optimalnost kod, temve

Praktina uporaba algoritmov stiskanja podatkov 5 kvejemu na to, kakšno kodo bo dobil posamezni simbol. V praksi to dejstvo predstavlja velik problem, saj obstaja ve razlinih enakovrednih dreves, iz katerih dobimo optimalne Huffmanove kode. Ker optimalne kode niso enoline, jih dekodirnik ne more izraunati. Zato moramo poleg kodiranih podatkov priložiti še Huffmanovo drevo, iz katerega smo pridobili kode. 3 ALGORITEM DEFLATE Kodirano zaporedje, ki ga tvori algoritem Deflate, se sestoji iz blokov poljubne dolžine. Vsak blok kodiramo loeno. Pri tem uporabimo algoritme RLE, LZ77 in Huffmanovo kodiranje v rahlo izboljšani obliki. Prva izboljšava: vsako ujemanje, ki ga najdemo v slovarju, predstavimo z dvojkom (dolžina ujemanja, odmik). Algoritem Deflate dovoljuje dolžino ujemanja od najmanj tri do najve dvestooseminpetdeset znakov. Simbole, ki jih ne najdemo v slovarju oz. je njihova dolžina ujemanja manjša od treh znakov, zapišemo brez kodiranja kot literale direktno v izhodni niz. Njihove vrednosti ležijo v intervalu [0..55]. Odmik je lahko podan z najve petnajstimi biti, zato je velikost slovarja omejena na 3 kb ( 5 =3768). Druga izboljšava: posebnost algoritma Deflate je tudi, kako poskuša najti najdaljše ujemanje v slovarju. Ni ga ne moti, e se ujemanje nadaljuje preko zadnjega znaka slovarja, t.j. v vhodno zaporedje, ki ga moramo šele obdelati. Uporaba te izboljšave ni obvezna. Primer: imejmo stavek»raunalnik rauna, rauna, rauna!«in slovar naj obsega besedi»raunalnik rauna,«.

Praktina uporaba algoritmov stiskanja podatkov 6... r a u n a, slovar r a u n a, r a u n a! besedilo Slika 3.: Algoritem Deflate (izboljšano iskanje v slovarju) Obdelujemo presledek. Ujemanje najdemo na odmiku 8. Po vrsti beremo znake vhodnega zaporedja, ki so vsi v slovarju, dokler ne pridemo do naslednjega presledka. Ker smo slovar izrpali, bi po izvornem algoritmu LZ77 zakljuili in v izhodno zaporedje zapisali (8,8, ). Algoritem Deflate pa spretno izkoriša ponavljanje in nadaljuje s primerjanjem vse dokler najde ujemanje. Tako v izhodno zaporedje zapiše (5,8) in zane z novim iskanjem za znak»!«. Spomnimo, da ima dvojek pri algoritmu Deflate na prvem mestu dolžino ujemanja, na drugem pa odmik. Tretja izboljšava: ki jo uporablja algoritem Deflate, je sekundarno iskanje. Najprej po že opisanem postopku doloimo najdaljše ujemanje. Nato shranimo prvo rko pravkar obdelane besede in poskušamo najti daljše ujemanje za preostanek. e nam uspe, v izhodni niz shranimo prvo rko kot literal, nato pa še dvojek za sekundarno ujemanje. V nasprotnem primeru shranimo dvojek za prvotno ujemanje. Uporaba te izboljšave ni obvezna. etrta izboljšava: ko gradimo Huffmanovo drevo, ne moremo vplivati, kje v drevesu se bo posamezni simbol pojavil. Tako lahko imamo dolge in kratke kode pomešane, dolge kode lahko nastopajo na levi strani drevesa, kratke na desni itd. Algoritem Deflate zahteva, da so kode urejene po dolžini od leve proti desni, kode enakih dolžin pa morajo biti urejene po simbolih, ki jih predstavljajo. Kode, ki jih dobimo iz takšnega drevesa, imenujemo kanonine Huffmanove kode in imajo lepo lastnost, da jih lahko predstavimo kot zaporedje dolžin. V splošnem Huffmanovo drevo ni urejeno, zato ga moramo najprej pretvoriti v kanonino obliko. Pri tem si lahko pomagamo s preprostim algoritmom, ki ga je napisal P. Deutsch []. Ideja je zelo uinkovita. Namesto, da urejamo drevo, rajši posameznim simbolom dodelimo nove kode, ki pa morajo biti enake dolžine kot prej. Sledi algoritem:

Praktina uporaba algoritmov stiskanja podatkov 7. Vse simbole imamo v tabeli Simbol[55]. Ugotovimo najdaljšo dolžino kode: MAXBITS 3. Preštejemo število simbolov za vsako dolžino in rezultat shranimo v tabelo Count[MAXBITS] for (int n = 0; n <= 55; n++) Count[dolžina kode za n-ti simbol]++ 4. Za vsako dolžino poišemo zaetno kodo in jo shranimo v tabelo NextCode[MAXBITS] Code = 0 Count[0] = 0 for (int bits = ; bits <= MAXBITS; bits++) { Code = (Code + Count[bits - ]) << NextCode[bits] = Code } 5. Posameznim simbolom dodelimo nove (zaporedne) kode for (int n = 0; n <= 55; n++) { int len=dolžina kode za n-ti simbol if (len!= 0) { Simbol[n] = NextCode[len] NextCode[len]++ } } Primer: Huffmanove kode iz tabele.3. pretvorimo v kanonine Huffmanove kode z uporabo zgoraj opisanega algoritma. Najprej kode predstavimo z zaporedjem njihovih dolžin: (n=3, l=5, i=5, R=4, a=, =3, k=4, r=4, =3, u=3). Vidimo, da je najdaljša dolžina kode 5 bitov: MAXBITS=5. Tvorimo tabelo Count[5]: Dolžina kode Število simbolov 0 0 0 3 4 4 3 5 Tabela 3.: Tabela Count[5] - število kod glede na njihovo dolžino

Praktina uporaba algoritmov stiskanja podatkov 8 Sedaj za vsako dolžino poišemo zaetno kodo in jo shranimo v tabelo NextCode[5]. Spomnimo, da operacija << pomeni množenje z (pomik bitov za eno mesto v levo). Ker nimamo nobene kode z dolžino, je NextCode[]=0: Code = (0 + Count[0]) << = 0. Imamo eno kodo z dolžino in NextCode[]=0: Code = (0 + Count[]) << = 0. Imamo štiri kode z dolžino 3 in NextCode[3]=: Code = (0 + Count[]) << =. Imamo tri kode z dolžino 4 in NextCode[4]=: Code = ( + Count[3]) << =. In konno imamo dve kodi z dolžino 5 in NextCode[5]=30: Code = ( + Count[4]) << = 30. Konna tabela izgleda takole: Dolžina kode NextCode[ ] 0 0 0 0 3 4 5 30 Tabela 3.: Tabela NextCode[5] z zaetnimi kodami za posamezne dolžine V zadnjem koraku generiramo nove kode. Simboli, ki ne nastopajo v vhodnem zaporedju, nimajo kode (dolžino kode je 0), zato jih preskoimo. Zaradi pogoja, da morajo biti kode enake dolžine urejene po simbolih, ki jih predstavljajo, je vrstni red dodeljevanja kod pomemben. Pravilni vrstni red zagotovimo, e tabelo simbolov obdelamo po ordinalnem vrstnem redu. Znaki z veljavno kodo so:, R, a, i, k, l, n, r, u in. Prvi je znak, dolžina njegove kode pa je 3 (glej tabelo.3.). Iz NextCode[3] dobimo njegovo novo kodo: (00 ). NextCode[3] poveamo za ena: NextCode[3]=3. Podobno obdelamo vse ostale simbole: Simbol Koda NextCode[ ] Nova koda Novi NextCode[ ] 00 NextCode[3]= 00 NextCode[3]=3 R 00 NextCode[4]= 00 NextCode[4]=3 a 0 NextCode[]=0 00 NextCode[]= i 000 NextCode[5]=30 0 NextCode[5]=3 k 00 NextCode[4]=3 0 NextCode[4]=4 l 0000 NextCode[5]=3 NextCode[5]=3 n 000 NextCode[3]=3 0 NextCode[3]=4 r 0 NextCode[4]=4 0 NextCode[4]=5 u NextCode[3]=4 00 NextCode[3]=5 0 NextCode[3]=5 0 NextCode[3]=6 Tabela 3.3: Kanonine Huffmanove kode

Praktina uporaba algoritmov stiskanja podatkov 9 Celotno drevo lahko zapišemo kot zaporedje dolžin: (3,4,,5,4,5,3,4,3,3) in vsak dekodirnik lahko dejanske kode izrauna po zgoraj opisanem algoritmu. Za pravilno predstavitev bi morali zaporedje zapisati z dvestošestinpetdesetimi dolžinami, kajti iz zgornjega zapisa lahko dekodirnik doloi kode za posamezni simbol, ne pa tudi kateremu simbolu koda pripada. Pravilen zapis bi bil: (0, 0, 0, 0, 3, 0,0,, 4, 0, 0, 0,,, 0, 0, 0, itd). V praksi algoritem deluje s celotnim naborom znakov z ordinalnimi vrednostmi od 0 do 55, ki pa po navadi ne nastopajo vsi pri kodiranju bloka. Tako ima zaporedje dolžin veliko zaporednih niel. Tudi simboli, ki so bili uporabljeni pri kodiranju, imajo zelo pogosto kode enakih dolžin. To pa so lastnosti, ki kar kliejo po uporabi algoritma RLE. 3. Naini kodiranja Algoritem Deflate kodira podatke v blokih. Dolžina bloka in število blokov sta poljubna, obiajno pa vsako datoteko kodiramo v svojem bloku. Prvi zlog bloka ima naslednji pomen: BFINAL (prvi bit): je za zadnji blok v nizu in 0 za vse ostale bloke. BTYPE (naslednja dva bita): oznaujeta vrsto kodiranja. Lahko imata vrednosti: 00-nekodirano, 0-kodirano s fiksnimi (vnaprej definiranimi) kodnimi tabelami in 0-kodirano z dinaminimi kodnimi tabelami. Nekodirano (BTYPE=00): prvi zlog bloka se zane z 000 ali 00. Preostali biti niso pomembni. Nato sledi dolžina bloka v zlogih (LEN) in eniški komplement istega podatka (NLEN). Obe števili sta nepredznaeni 6-bitni števili, zato je dolžina bloka omejena na 64 kb ( 6 =65535). Sledijo nekodirani podatki. Kodirano z vnaprej definiranimi kodnimi tabelami (BTYPE=0): prvi zlog bloka se zane z 00 ali 0. Simbol v kodiranem bloku je lahko: nekodiran znak oz. literal (vrednosti iz intervala [0..55]) ali pa dvojek (dolžina ujemanja, odmik), kjer je dolžina ujemanja iz intervala [3..58] in odmik iz intervala [..3768]. Literale in dolžine ujemanja združimo v eno kodno tabelo z vrednostmi iz intervala [0..87].

Praktina uporaba algoritmov stiskanja podatkov 0 Vrednosti iz intervala [0..55] pripadajo literalom, vrednost 56 predstavlja konec bloka, vrednosti [57..87] pa predstavljajo dolžine ujemanja. Ker se kodi 86 in 87 ne smeta uporabljati (sta rezervirani), dobimo uporaben interval v razponu [0..85]. Slednjih devetindvajset kod iz intervala [57..85] je premalo, da bi lahko enolino kodirali dvestošestinpetdeset dolžin ujemanja iz intervala [3..58], zato jim dodamo dodatne bite kot prikazuje tabela 3... Tabela 3.. prikazuje Huffmanove kode za literale/dolžine ujemanja, ki jih zapisujemo v izhodni kodirani blok. Koda Dodatni biti Dolžina Koda Dodatni biti Dolžina Koda Dodatni biti Dolžina 57 0 3 67 5-6 77 4 67-8 58 0 4 68 7-8 78 4 83-98 59 0 5 69 9-79 4 99-4 60 0 6 70 3-6 80 4 5-30 6 0 7 7 7-30 8 5 3-6 6 0 8 7 3-33 8 5 63-94 63 0 9 73 3 35-4 83 5 95-6 64 0 0 74 3 43-50 84 5 7-57 65-75 3 5-58 85 0 58 66 3-4 76 3 59-66 Tabela 3..: Kodna tabela za dolžine ujemanja Koda Dolžina Huffmanova koda 0-43 8 000000-0 44-55 9 000000-56-79 7 0000000-000 80-87 8 000000-000 Tabela 3..: Huffmanove kode za literale/dolžine ujemanja Primer: kako z uporabo zgornjih tabel kodiramo dolžine ujemanja? (A) e je algoritem LZ77 v slovarju našel niz dolžine štirih znakov, ji pripada koda 58 (glej tabelo 3..), Huffmanova koda za 58 pa se glasi 000000 (glej tabelo 3..). To kodo zapišemo v izhodni kodirani blok. (B) e najdemo ujemanje dolžine dvanajstih znakov, ji pripada koda 65, ustrezna Huffmanova koda pa je 00000. Da loimo med dolžinama enajst in dvanajst znakov (obema pripada koda 65), moramo dodati še en bit: za dolžino enajst je ta bit 0, za dolžino dvanajst pa. Cela koda se tako glasi: 00000{}. Dodatni bit je v oklepajih zaradi lepšega prikaza. (C) Za ujemanje dolžine

Praktina uporaba algoritmov stiskanja podatkov štiriindvajsetih znakov dobimo kodo 70, Huffmanova koda je: 0000{0}. (D) Za dolžino dvestošestinpetdeset dobimo kodo 84, Huffmanova koda pa se glasi: 00000{0}. (E) Kodo 56, ki oznauje konec bloka, zapišemo kot 0000000. Za kodiranje odmikov potrebujemo drugo tabelo s kodami iz intervala [0..3]. Kodi 30 in 3 se ne smeta uporabljati (sta rezervirani). Tako dobimo trideset uporabnih kod, ki jih lahko predstavimo s petimi biti. Ker pa je lahko odmik v intervalu [..3768], potrebujemo za njegovo enolino kodiranje dodatne bite. Kode so prikazane v tabeli 3..3. Koda Dodatni biti Odmik Koda Dodatni biti Odmik Koda Dodatni biti Odmik 0 0 0 4 33-48 0 9 05-536 0 4 49-64 9 537-048 0 3 5 65-96 0 049-307 3 0 4 3 5 97-8 3 0 3073-4096 4 5-6 4 6 9-9 4 4097-644 5 7-8 5 6 93-56 5 646-89 6 9-6 7 57-384 6 893-88 7 3-6 7 7 385-5 7 89-6384 8 3 7-4 8 8 53-768 8 3 6385-4576 9 3 5-3 9 8 769-04 9 3 4577-3768 Tabela 3..3: Huffmanove kode za odmike Primer: kako z uporabo zgornje tabele kodiramo odmike? (A) Iz tabele je razvidno, da odmiku 5 pripada koda 4 z enim dodatnim bitom: 0000{0}. Odmik 6 bi kodirali kot 0000{}. (B) Odmiku 80 pripada koda 4 s šestimi dodatnimi biti: 00{00}. Koda za odmik 80 je enainpetdeseta koda iz intervala [9..9], zato: 5 = 33 6 = 00. (C) Odmiku 895 pripada koda 6 z dvanajstimi dodatnimi biti: 00{00000000000}. Primer: uporabimo algoritem Deflate z vnaprej definiranimi kodnimi tabelami nad nizom Raunalnik rauna. Algoritem LZ77 nam da zaporedje: Raunalnik r(5,). ASCII kode za literale so: R=8 (5 6 ), a=97 (6 6 ), =3 (E8 6 ), u=7 (75 6 ), n=0 (6E 6 ), a=97 (6 6 ), l=08 (6C 6 ), n=0 (6E 6 ), i=05 (69 6 ), k=07 (6B 6 ), =3 (0 6 ) in r=4 (7 6 ). To zaporedje sedaj kodirajmo. Ker bomo imeli samo en blok, se trije kontrolni biti bloka glasijo: 0. Znak R ima ASCII kodo 8 (5 6 ), zato spada v interval kod [0..43], ki se zanejo pri 000000 (30 6 ). e seštejemo 30 6 in 5 6, dobimo kodo: 8 6, zato v kodirani blok zapišemo: 000000. Za znak a dobimo: 30 6 + 6 6 = 9 6 in v kodirani blok zapišemo: 00000. Znak ima kodo 3 (E8 6 ), zato spada v

Praktina uporaba algoritmov stiskanja podatkov interval kod [44..55], ki se zanejo pri 000000 (90 6 ). Koda 3 je oseminosemdeseta koda v tem zaporedju: 3-4=88 (58 6 ). e seštejemo 90 6 + 58 6, dobimo kodo E8 6 in v kodirani blok zapišemo: 0000. Po istem postopku kodiramo tudi vse ostale literale: u=0000 n=000 a=00000 l=0000 n=000 i=0000 k=000 =000000 r=00000. Kodirati moramo še dvojek (5,). Dolžina 5 nam da kodo 59, ki jo kodiramo s sedmimi biti: 00000 (glej tabeli 3.. in 3..). Odmik kodiramo s pomojo tabele 3..3. Za odmik dobimo kodo 6, potrebujemo pa še dva dodatna bita. Dobimo: 000{0}. Na konec bloka moramo dodati še kodo 56: 0000000. Celoten kodirani blok se glasi: 0 000000 00000 0000 0000 000 00000 0000 000 0000 000 000000 00000 00000 0000 0000000. Obe kodni tabeli sta vgrajeni v kodirnik in dekodirnik, zato ju ni potrebno prilagati h kodiranemu bloku. Kodirani podatki sledijo takoj za tremi kontrolnimi biti prvega zloga. Blok se zakljui s Huffmanovo kodo za simbol 56: 0000000. Kodirano z dinaminimi kodnimi tabelami (BTYPE=0): prvi zlog bloka se zane z 00 ali 0. Sledijo opisi kodnih tabel: Število kod v tabeli literalov/dolžin (HLIT): pet bitov. Literali lahko zavzamejo vrednosti iz intervala [0..55], vrednost 56 predstavlja konec bloka, vrednosti iz intervala [57..85] pa predstavljajo dolžine (glej tabelo 3..). Nekatere dolžine lahko manjkajo, zato HLIT pove, katera koda dolžine je zadnja uporabljena (npr. e je zadnja uporabljena koda dolžine enaka 59, je HLIT enak : 59-57 = ). Število kod v tabeli odmikov (HDIST): pet bitov. V tabeli je trideset kod (glej tabelo 3..3), ker pa nekatere kode lahko manjkajo, HDIST pove, kateri odmik je zadnji uporabljen (npr. e je zadnji uporabljeni odmik s kodo 6, je HDIST enak 6). Število kod v tabeli (HCLEN), s katerimi sta kodirani tabeli literalov/dolžin in odmikov: štirje biti. Vrednosti so lahko iz intervala [0..5], pomenijo pa kode iz intervala [4..9]. Ker nekatere kode lahko manjkajo, (HCLEN + 4) pove, koliko kod je v tabeli. Zaporedje dolžin (HCLIST) za kode, s katerimi sta kodirani tabeli literalov/dolžin in odmikov. Spomnimo, da namesto kod v kanonini

Praktina uporaba algoritmov stiskanja podatkov 3 obliki lahko pišemo zaporedje dolžin, iz katerega lahko rekonstruiramo kodno tabelo. Vseh dolžin je (HCLEN+4), vsaka je dolžine treh bitov. Zaporedje dolžin (HLITLIST) za kode iz tabele literalov/dolžin. Vseh dolžin je (57+HLIT) in so kodirane po postopku, opisanem v poglavju 3.. Zaporedje dolžin (HDISTLIST) za kode iz tabele odmikov. Vseh dolžin je (HDIST+) in so kodirane po postopku, opisanem v poglavju 3.. Sledijo kodirani podatki: podatki so kodirani s pomojo obeh kodnih tabel za literale/dolžine in odmike. Koda za konec bloka: Huffmanova koda za simbol 56. 3. Dinamine kodne tabele Kodirnik med postopkom kodiranja sam generira dve kodni tabeli, eno za literale/dolžine ujemanja in drugo za odmike. Tabeli dobimo iz Huffmanovih dreves. Kakšno bo drevo, je povsem odvisno od algoritma. Bolj izpopolnjen algoritem lahko zbere boljšo statistiko in tako generira krajši izhodni niz. Slabši algoritem se bo morda zadovoljil s krajšim ujemanjem, a bo kodiranje hitrejše. Pri izbiri algoritma moramo tako vedno delati kompromis med hitrostjo kodiranja in velikostjo kodiranega niza. Ker se tabeli tvorita dinamino glede na vhodne podatke, ju moramo priložiti k vsakemu kodiranemu bloku. Algoritem Deflate kodni tabeli zapiše v zelo strnjeni obliki. V grobem je postopek za zapis kodnih tabel sledei: Za vsako od obeh tabel (tabela literalov/dolžin in tabela odmikov) zgradimo Huffmanovo drevo. Obe Huffmanovi drevesi pretvorimo v kanonino obliko. Kanonine kode zapišemo kot zaporedje dolžin. Vsako drevo ima svoje zaporedje dolžin: S LIT in S DIST, Obe zaporedji dolžin združimo v eno zaporedje S = S LIT + S DIST, pri emer nile s konca posameznega zaporedja odstranimo. Novo zaporedje S kodiramo z algoritmom RLE, da dobimo še krajše

Praktina uporaba algoritmov stiskanja podatkov 4 zaporedje S RLE. Iz krajšega zaporedja S RLE zgradimo novo Huffmanovo drevo. Novo Huffmanovo drevo pretvorimo v kanonino obliko. Kode iz tako dobljenega drevesa predstavimo z zaporedjem dolžin. Zapišemo dolžine za vse kode [0..8], neuporabljene kode inicializiramo na 0. Zaporedje premešamo. Vrstni red je predpisan in sicer si kode sledijo v tem zaporedju: 6 7 8 0 8 7 9 6 0 5 4 3 3 4 5. Odstranimo nile s konca zaporedja, preostanek pa zapišemo v glavo kodiranega bloka (HCLIST). Zaporedje S RLE kodiramo s prej pridobljenimi kanoninimi Huffmanovimi kodami. Zaporedje zapišemo v glavo kodiranega bloka takoj za zaporedjem (HCLIST) in predstavlja kodirani tabeli za literale/dolžine (HLITLIST) in odmike (HDISTLIST). Postopek kodiranja z algoritmom RLE: kako pridemo do Huffmanovih kod, smo opisali v poglavju.3. Tudi pretvorbo Huffmanovih kod v kanonine Huffmanove kode smo že opisali v poglavju 3 (etrta izboljšava). Zato na tem mestu predpostavimo, da zaporedje dolžin že imamo. Dolžine v tem zaporedju se obiajno ponavljajo, zato jih lahko dobro stisnemo z uporabo algoritma RLE, da dobimo še krajše zaporedje. Algoritem Deflate iz vhodnega zaporedja dolžin tvori novo zaporedje in sicer na naslednji nain: e se dolžina ponovi trikrat ali manj, jo prepišemo v novo zaporedje. e se dolžina ponovi ve kot trikrat, jo kodiramo z uporabo algoritma RLE. V novo zaporedje zapišemo dolžino, ki ji sledi koda 6 in število ponovitev (kolikokrat se dolžina ponovi). Število ponovitev je dolžine dveh bitov in oznauje od tri do šest ponovitev (00 predstavlja tri ponovitve, predstavlja šest ponovitev). Izkušnje kažejo, da se dolžina ni pojavlja zelo pogosto, zato ima dve posebni kodi. Prva posebna koda je 7, ki ji sledi 3-bitno število, ki

Praktina uporaba algoritmov stiskanja podatkov 5 pomeni od tri do deset ponovitev (000 predstavlja tri ponovitve, predstavlja deset ponovitev). Druga posebna koda je 8, ki ji sledi 7- bitno število, ki pomeni od enajst do stoosemintrideset ponovitev (0000000 predstavlja enajst ponovitev, predstavlja stoosemintrideset ponovitev). Primer: uporabe algoritma RLE. (A) Kako kodiramo šest zaporednih sedmic: 7, 7, 7, 7, 7, 7? Zapišemo: 7 6 0 (00 so tri ponovitve, 0 so štriri ponovitve, 0 je pet ponovitev in je šest ponovitev). Torej, prva sedmica in pet ponovitev, nam da šest zaporednih sedmic. (B) Kako kodiramo enajst zaporednih štiric: 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4? Pišemo: 4 6 6 0. (C) Kako kodiramo deset zaporednih niel? Pišemo: 7. (D) Kako kodiramo dvajset zaporednih niel? Pišemo: 8 00000 (koda 0 je deveta koda iz intervala [..38]). Primer: stavek»raunalnik rauna«kodirajmo z dinaminimi kodnimi tabelami. () Algoritem LZ77 nam da naslednje zaporedje: R, a,, u, n, a, l, n, i, k,, r, (5,). Abeceda literalov/dolžin vsebuje simbole z ordinalnimi vrednostmi iz intervala [0..87]. Spomnimo, da kod 86 in 87 ne smemo uporabljati, vendar morata vseeno sodelovati pri gradnji Huffmanovega drevesa. Dolžina 5 nam da kodo 59 (glej tabelo 3..), ki jo bomo predstavili s simbolom d 59. Simbol za konec bloka bomo oznaili z EOB. Z uporabo Huffmanovega kodiranja dobimo enega izmed naborov Huffmanovih kod: Simbol Ord. vred. Huffmanova koda Kanonina Huffmanova koda 3 000 00 R 8 000 0 a 97 00 i 05 00 000 k 07 0 00 l 08 000 00 n 0 00 00 r 4 00 0 u 7 0000 00 3 00 0 EOB 56 00 0 d 59 59 0 Tabela 3..: Huffmanove kode in kanonine Huffmanove kode za literale/dolžine Zaporedje dolžin, s katerim predstavimo kanonine Huffmanove kode, se glasi: 0{3}, 4, 0{49}, 4, 0{4},, 0{7}, 4, 0, 4, 4, 0, 3, 0, 0, 0, 4, 0, 0, 4, 0{4}, 4, 0{3}, 4, 0, 0, 4, 0{8}. Da je zaporedje

Praktina uporaba algoritmov stiskanja podatkov 6 bolj pregledno, smo ponovitve niel zapisali v zavitih oklepajih. () Podobno moramo storiti tudi za odmike. V našem primeru imamo samo en odmik:, kar nam da kodo 6 (glej tabelo 3..3) z dvema dodatnima bitoma: 0. Huffmanovo drevo je trivialno, z enim samim vozlišem, ki mu priredimo kodo 0. e bi imeli ve odmikov, bi s pomojo tabele 3..3 in Huffmanovega kodiranja za vsak odmik doloili kanonino Huffmanovo kodo. Ustrezno zaporedje dolžin se glasi: 0{6},, 0{5}. eprav kod 30 in 3 ne smemo uporabljati, morata vseeno sodelovati pri gradnji Huffmanovega drevesa, zato ima zaporedje dvaintrideset elementov. (3) Oba zaporedja dolžin združimo v eno zaporedje, kjer lahko ponavljajoe se nile na koncu posameznega zaporedja izpustimo. Dobimo: 0{3}, 4, 0{49}, 4, 0{4},, 0{7}, 4, 0, 4, 4, 0, 3, 0, 0, 0, 4, 0, 0, 4, 0{4}, 4, 0{3}, 4, 0, 0, 4, 0{6},. Dobljeno zaporedje kodiramo z algoritmom RLE: 8 0000 4 8 0000 4 8 00000 7 00 4 0 4 4 0 3 7 000 4 0 0 4 8 00 4 8 00000 4 0 0 4 7 0. (4) Za novo zaporedje generiramo Huffmanove kode. V abecedi za Huffmanovo drevo sodelujejo samo simboli iz intervala [0..8], bitne vrednosti so dopolnilo h kodam in jih ne kodiramo. Imamo simbole: 8, 4, 8, 4, 8,, 7, 4, 0, 4, 4, 0, 3, 7, 4, 0, 0, 4, 8, 4, 8, 4, 0, 0, 4, 7 in. Pri Huffmanovem kodiranju potrebujemo tudi njihove frekvence, zato zapišimo še te: 0{6}, {}, {}, 3{}, 4{0}, 7{3} in 8{5}. Simbol Huffmanova koda Kanonina Huffmanova koda 0 0 00 0 0 000 0 3 00 4 00 0 7 00 0 8 0 Tabela 3..: Huffmanove kode in kanonine Huffmanove kode za zaporedje RLE (5) Zapišimo zaporedje dolžin za vse simbole [0..8]: 0 3 4 5 6 7 8 9 0 3 4 5 6 7 8 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 3 in ga premešajmo v skladu s predpisom:

Praktina uporaba algoritmov stiskanja podatkov 7 6 7 8 0 8 7 9 6 0 5 4 3 3 4 5 0 3 0 0 0 0 0 0 0 0 5 0 5 0 4 0 (6) Odstranimo nile s konca zaporedja: v našem primeru imamo na koncu samo eno nilo, zato v kodirani blok zapišemo zaporedje prvih osemnajstih števil. To je naše zaporedje HCLIST, ki ga zapišemo v glavo kodiranega bloka: 0 3 0 0 0 0 0 0 0 0 5 0 5 0 4. Primer: za prejšnji primer zapišimo celotno glavo bloka: () Trije biti na zaetku bloka: 0. () Pet bitov za HLIT: (0000 ). Zadnji uporabljeni simbol v tabeli literalov/dolžin je simbol 59 (59-57 = ). (3) Pet bitov za HDIST: 6 (000 ). Zadnji uporabljeni simbol iz tabele odmikov je 6. (4) Štirje biti za HCLEN: 4 (0 ). Pomenijo, da imamo 8 kod (HCLEN+4). (5) Zaporedje dolžin HCLIST. V prejšnjem primeru smo dobili: 0 3 0 0 0 0 0 0 0 0 5 0 5 0 4. Vsako dolžino zapišemo kot 3-bitno število: 000 0 00 00 000 000 000 000 000 000 000 00 000 0 000 0 000 00. (6) Zaporedje, kodirano z algoritmom RLE, kodiramo še s kanoninimi Huffmanovimi kodami: 8 0000 4 8 0000 4 8 00000 7 00 4 0 4 4 0 3 7 000 4 0 0 4 8 00 4 8 00000 4 0 0 4 7 0 0. Dobimo: 0 0000 0 0 0000 0 0 00000 0 0 00 0 00 0 0 00 0 000 0 00 00 0 0 00 0 0 00000 0 00 00 0 0 0 0 0. To zaporedje nam predstavlja obe kodni tabeli za literale/dolžine (HLITLIST) in odmike (HDISTLIST). (7) Sledijo podatki, kodirani s pomojo obeh kodnih tabel: R=0, a=00, =0, u=00, n=00, a=00, l=00, n=00, i=000, k=00, =00, r=0, dolžina 5=d 59 =, odmik =0 0. (8) Konec bloka: koda za simbol 56=0. Ker je postopek kodiranja bitno naravnan, povejmo še, kako moramo združevati bite, da bodo podatki pravilno predstavljeni. Vsa števila so predstavljena v obliki: b7 b6 b5 b4 b3 b b b0, kjer je najmanj pomemben bit b0 na desni in najbolj pomemben bit b7 na levi. Bite polnimo po vrsti od b0 do b7: Vse vrednosti, ki niso Huffmanove kode, zapišemo po bitih od najmanj pomembnega proti najbolj pomembnemu bitu. Huffmanove kode podajamo v obratnem vrstnem redu, t.j. bite

Praktina uporaba algoritmov stiskanja podatkov 8 zapisujemo od najbolj pomembnega proti najmanj pomembnemu bitu. Primer: blok, kodiran z dinaminimi kodnimi tabelami, mora imeti na zaetku oznako 0. Sledi mu 5-bitno število uporabljenih kod v tabeli literalov/dolžin, HLIT. Recimo, da je HLIT=7. Tedaj prvi zlog bloka zapišemo: 00 0 (b0=, b=0, b=, b3=, b4=, b5=, b6=0 in b7=0). Huffmanovo kodo 0 moramo zapisati v obratnem vrstenm redu: 0 (b0=, b=0, b=, b3= itd). 4 STRUKTURA DATOTEKE ZIP Datoteke ZIP so namenjene arhiviranju in izmenjevanju podatkov. Za specifikacijo [5] skrbi podjetje PKWare Inc., katerega ustanovitelj je bil P. W. Katz (96 000), ki je med drugim tudi avtor algoritma Deflate. Mi se bomo omejili na osnovno zgradbo datoteke ZIP, ki bo omogoala zgolj arhiviranje in branje arhivskih datotek. Izpustili pa bomo razline možnosti kodiranja ZIP datotek, uporabo certifikatov in kreiranje velikih Zip64 arhivov, ki dovoljujejo arhiviranje datotek, vejih od 4 GB. Ni nujno, da se arhiv ZIP nahaja v eni datoteki ZIP. Lahko ga razbijemo na ve delov poljubne dolžine, npr. za prenos podatkov z disketo. Poznamo dve vrsti segmentiranja. Kadar arhiv delimo na ve disket, je ime arhiva na vseh disketah enako, npr. Podatki008090.ZIP. Številko segmenta razberemo iz oznake diskete (angl. volume label) in mora biti v obliki PKBACK#nnn, kjer nnn predstavlja številko segmenta. Pri delitvi na disk moramo upoštevati, da v mapi ne moreta obstajati dve datoteki z enakim imenom. Zato ima samo zadnja datoteka (segment) konnico ZIP, vse prejšnje pa imajo številko segmenta v imenu. Primer: e datoteko Podatki008090.ZIP razbijemo na tri segmente v isto mapo, morajo biti ustrezna imena datotek: Podatki008090.Z0, Podatki008090.Z0 in Podatki008090.ZIP. Datoteke, ki jih dodamo v arhiv ZIP, so lahko shranjene v poljubnem vrstnem redu. Celotna zgradba datoteke ZIP je naslednja (elementi, ki so obarvani sivo, za

Praktina uporaba algoritmov stiskanja podatkov 9 našo aplikacijo niso potrebni in jih ne bomo opisovali. Celoten opis lahko bralec najde v [5]): (A) prva datoteka: opis (local file header ) (B) prva datoteka: kodirani podatki (file data ) (C) [prva datoteka: dodatni opis (data descriptor )] (A) N-ta datoteka: opis (local file header N) (B) N-ta datoteka: kodirani podatki (file data N) (C) [N-ta datoteka: dodatni opis (data descriptor N)] (D) [Podatki za dekodiranje (archive decryption header)] (E) [Dodatni podatki (archive extra data record)] (F) Katalog (central directory) (G) [Konec ZIP64 kataloga (ZIP64 end of central directory record)] (H) [Konec ZIP64 lokatorja (ZIP64 end of central directory locator)] (I) Konec kataloga (end of central directory) (A) Opis datoteke (local file header): pred vsako kodirano datoteko moramo zapisati blok z osnovnimi podatki o datoteki. eprav so ti podatki na voljo tudi v katalogu na koncu datoteke ZIP, jih moramo navajati tudi pred kodiranimi podatki in sicer zaradi naprav, ki ne omogoajo nakljunega iskanja. A.: ID bloka (local file header signature) 4 zlogi Mora biti 04035b50 6 A.: Minimalna verzija za dearhiviranje (version needed to extract) zloga.0: privzeto.: datoteka predstavlja disk.0: datoteka predstavlja mapo.0: datoteka je stisnjena z algoritmom Deflate.0: datoteka je zašitena (kodirana) z osnovnim algoritmom PKWARE.: datoteka je stisnjena z algoritmom Deflate64.5: datoteka je stisnjena s algoritmom PKWARE DCL Implode.7: datoteka je popravek (patch) 4.5: datoteka uporablja format ZIP64

Praktina uporaba algoritmov stiskanja podatkov 30 4.6: datoteka je stisnjena z algoritmom BZIP 5.0: datoteka je zašitena (kodirana) z algoritmom DES 5.0: datoteka je zašitena (kodirana) z algoritmom 3DES 5.0: datoteka je zašitena (kodirana) z originalnim algoritmom RC 5.0: datoteka je zašitena (kodirana) z algoritmom RC4 5.: datoteka je zašitena (kodirana) z algoritmom AES 5.: datoteka je zašitena (kodirana) s spremenjenim algoritmom RC 5.: datoteka je zašitena (kodirana) s spremenjenim algoritmom RC-64 6.: katalog je zašiten (kodiran) 6.3: datoteka je stisnjena z algoritmom LZMA 6.3: datoteka je stisnjena z algoritmom PPMd+ 6.3: datoteka je zašitena (kodirana) z algoritmom BlowFish 6.3: datoteka je zašitena (kodirana) z algoritmom TwoFish A.3: Zastavice (general purpose bit flag) zloga Bit 0: mora biti, e je datoteka zašitena (kodirana) Bit in (odvisno od uporabljenega algoritma stiskanja). Za algoritem Deflate: 00: uporabljen je normalni faktor stiskanja 0: uporabljen je maksimalni faktor stiskanja 0: uporabljeno je hitro stiskanje : uporabljeno je super hitro stiskanje Bit 3: e, ima datoteka tudi blok za dodatni opis Bit 4: rezervirano za algoritem Deflate64 Bit 5: e, je datoteka popravek (patch) Bit 6: mora biti, e je datoteka zašitena (kodirana) z naprednejšimi algoritmi, npr. DES, 3DES, AES itd. Bit 7, 8, 9 in 0: trenutno neuporabljeni, morajo biti 0 Bit : e, je ime datoteke kodirano z UTF-8 Bit : rezervirano (PKWARE) Bit 3 (se uporablja samo, e je katalog zašiten): e je, oznauje, da so vrednosti v opisu datoteke maskirane (skrivanje pravih vrednosti) Bit 4 in 5: rezervirano (PKWARE) A.4: Uporabljen algoritem stiskanja (compression method) zloga 0 brez stiskanja Shrink (spremenjen algoritem LZW) Reduce: uporabljen je faktor stiskanja 3 Reduce: uporabljen je faktor stiskanja 4 Reduce: uporabljen je faktor stiskanja 3 5 Reduce: uporabljen je faktor stiskanja 4 6 Implode

Praktina uporaba algoritmov stiskanja podatkov 3 7 Tokenizing 8 Deflate 9 Deflate64 0 PKWARE DCL Implode Rezervirano (PKWARE) BZIP 3 Rezervirano (PKWARE) 4 LZMA 5 Rezervirano (PKWARE) 6 Rezervirano (PKWARE) 7 Rezervirano (PKWARE) 8 IBM TERSE 9 IBM LZ77 97 WavPack 98 PPMd ver. A.5: as zadnje spremembe (last modification file time) zloga as v formatu MS-DOS A.6: Datum zadnje spremembe (last modification file date) zloga Datum v formatu MS-DOS A.7: Kontrolna koda (CRC-3) 4 zlogi Glej poglavje 5 A.8: Velikost stisnjene datoteke (compressed size) 4 zlogi A.9: Velikost originalne datoteke (uncompressed size) 4 zlogi A.0: Dolžina imena datoteke (file name length) FNAMELEN zloga A.: Dolžina polja za dodatne podatke (extra field length) EXTRALEN zloga A.: Ime datoteke (file name) FNAMELEN Ime datoteke (ki lahko vsebuje tudi relativno pot). Pot ne sme vkljuevati oznake pogona ali diska. Loilo med mapami mora biti»/«. A.3: Dodatni podatki (extra field) EXTRALEN Za razširitve, npr. e želimo shraniti dodatne informacije o datoteki. Predpisana je oblika: HEAD+DATA+HEAD+DATA, pri emer je HEAD definiran kot: ID bloka (HEAD ID): zloga Dolžina bloka (HEAD LEN): zloga (B) Kodirani podatki (file data): datoteka mora biti kodirana z enim izmed predpisanih algoritmov (glej A.4). Kodirani podatki takoj sledijo bloku (A) Opis datoteke.

Praktina uporaba algoritmov stiskanja podatkov 3 (F) Katalog (central directory): katalog vseh datotek v arhivu ZIP. Služi za hiter dostop do podatkov vseh datotek, ki se nahajajo v arhivu. Zgradba bloka je naslednja: F.: opis prve datoteke (file header ) F.: opis druge datoteke (file header ) F.: opis N-te datoteke (file header N) F.: [digitalni podpis] F.: opis datoteke v katalogu (file header): opis posamezne datoteke (za hiter prikaz in dostop do podatkov datoteke). F..: ID bloka (central file header signature) 4 zlogi Mora biti 004b50 6 F..: Verzija programa (version made by) zloga Zgornji zlog (MSB) predstavlja kompatibilnost z operacijskim sistemom. Vrednosti so predpisane in pomenijo sledee: 0 MS-DOS in OS/ (FAT, VFAT in FAT3) Amiga OpenVMS 3 UNIX 4 VM/CMS 5 Atari ST 6 OS/ HP FS 7 MacIntosh 8 Z-system 9 CP/M 0 Windows NTFS MVS VSE 3 Acorn RISC 4 VFAT 5 Alternate MVS 6 BeOS 7 Tandem

Praktina uporaba algoritmov stiskanja podatkov 33 8 OS/400 9 OS/X Spodnji zlog (LSB) predstavlja specifikacijo, ki jo program podpira. Npr. za verzijo 6.3 je LSB enak 63. F..3: Minimalna verzija za dearhiviranje (version needed to extract) zloga Enako kot v A. F..4: Zastavice (general purpose bit flag) zloga Enako kot v A.3 F..5: Uporabljen algoritem stiskanja (compression method) zloga Enako kot v A.4 F..6: as zadnje spremembe (last modification file time) zloga Enako kot v A.5 F..7: Datum zadnje spremembe (last modification file date) zloga Enako kot v A.6 F..8: Kontrolna koda (CRC-3) 4 zlogi Enako kot v A.7 F..9: Velikost stisnjene datoteke (compressed size) 4 zlogi F..0: Velikost originalne datoteke (uncompressed size) 4 zlogi F..: Dolžina imena datoteke (file name length) FNAMELEN zloga F..: Dolžina polja za dodatne podatke (extra field length) EXTRALEN zloga F..3: Dolžina komentarja (file comment length) - COMMLEN zloga F..4: Zaetna številka segmenta (disk number start) zloga Številka segmenta (datoteke), kjer so dejanski podatki za datoteko iz tega bloka F..5: Interni datoteni atributi (internal file attributes) zloga Bit 0: e 0, je datoteka binarna. e, je datoteka tekstovna Bit in : rezervirano (PKWARE) Ostali biti so neuporabljeni F..6: Zunanji datoteni atributi (external file attributes) 4 zlogi Odvisno od operacijskega sistema F..7: Odmik do podatkov datoteke (relative offset of local file header) 4 zlogi Odmik, kjer se zanejo podatki za datoteko iz tega bloka. Odmik kaže na zaetek bloka A opis datoteke (local file header) glede na F..4 F..8: Ime datoteke (file name) FNAMELEN F..9: Dodatni podatki (extra field) EXTRALEN F..0: Komentar (file comment) COMMLEN

Praktina uporaba algoritmov stiskanja podatkov 34 (I) Konec kataloga (end of central directory): dodatne informacije o arhivu ZIP. I.: ID bloka (end of central directory signature) 4 zlogi Mora biti 06054b50 6 I.: Številka segmenta (number of this disk) zloga Številka segmenta (datoteke), ki vsebuje blok (I) Konec kataloga I.3: Številka segmenta, kjer se zane katalog (number of disk with zloga the start of central directory): katalog se lahko razteza ez ve segmentov (datotek), zato s tem poljem povemo, v katerem segmentu je zaetek kataloga I.4: Število datotek v katalogu v tem segmentu (total number of entries zloga in the central directory on this disk) I.5: Število vseh datotek v katalogu (total number of entries in the zloga central directory): število vseh datotek v celotnem arhivu, ne glede na to ali se katalog razteza ez ve segmentov (datotek) I.6: Velikost kataloga v zlogih (size of central directory) 4 zlogi I.7: Odmik do zaetka kataloga (offset to start of central directory 4 zlogi with respect to I.3) I.8: Dolžina komentarja (ZIP file comment length) - COMMLEN zloga I.9: Komentar (ZIP file comment) COMMLEN 5 KODA CRC Osnovni namen kode CRC (angl. cyclic redundancy code ali tudi cyclic redundancy check) je ugotavljanje, ali je bilo doloeno sporoilo spremenjeno. Sporoilo je lahko spremenjeno iz razlinih razlogov: zaradi napake pri prenosu (npr. preko omrežne povezave), zaradi napake medija (npr. pri zapisovanju na disk ali branju z njega), pri prenosu od uporabnika A do uporabnika B bi ga lahko spremenil uporabnik C itd. Torej služi kot neke vrste podpis. Oddajnik iz vsebine sporoila izrauna kodo CRC in jo pripne k sporoilu. Na drugi strani prejemnik iz prejetega sporoila prav tako izrauna kodo CRC. e dobi rezultat razlien od ni, lahko z gotovostjo trdi, da je bilo sporoilo spremenjeno. V nasprotnem primeru je lahko skoraj stoodstotno gotov, da je

Praktina uporaba algoritmov stiskanja podatkov 35 sporoilo nespremenjeno. Stoodstotne zanesljivosti ne moremo dosei, kajti razlina sporoila lahko tvorijo enako kodo CRC, na kar pa nimamo vpliva. Tako dopušamo možnost, da bi tudi iz spremenjenega sporoila dobili enako kodo CRC kot iz originala, vendar je verjetnost za kaj takega dovolj majhna, da jo lahko zanemarimo. e si zamislimo, da je naše sporoilo dolgo binarno število, ga lahko delimo z drugim binarnim številom, preostanek pa predstavlja kodo CRC. Obiajno obe števili predstavimo kot polinoma. Deljenje polinomov je v matematiki dobro poznano, v raunalništvu pa so si omislili številne poenostavljene aritmetike in eno izmed njih uporabljamo tudi pri raunanju kode CRC. Imenujemo jo aritmetika MOD, nekateri avtorji pa ji pravijo tudi aritmetika CRC. Ker raunamo v dvojiškem sistemu, koeficienti ob spremenljivki odpadejo, saj so lahko le ni ali ena. Torej upoštevamo samo spremenljivke s koeficientom ena. Npr. binarno število 000 lahko zapišemo kot polinom: X 6 + 0 X 5 + X 4 + X 3 + 0 X + 0 X + X 0 = X 6 + X 4 + X 3 +. Druga poenostavitev je, da vse raunske operacije izvajamo brez prenosa. Ob teh predpostavkah lahko v naši aritmetiki definiramo osnovne štiri operacije: seštevanje, odštevanje, množenje in deljenje. Seštevanje Odštevanje 00 00 + 00-00 00 00 Slika 5.: Primer seštevanja in odštevanja dveh števil v aritmetiki CRC Kot lahko opazimo, obe operaciji dajeta enak rezultat, hkrati pa zelo prikladno sovpadata z drugim binarnim operatorjem, ki ga v raunalništvu dokaj pogosto uporabljamo, t.j. operator XOR ( ). Takšen rezultat ima za posledico še eno zanimivo lastnost: primerjava dveh števil je možna samo na najvišjem koeficientu (bitu).

Praktina uporaba algoritmov stiskanja podatkov 36 Primer: v aritmetiki CRC ne moremo trditi, da je število 00 veje od števila 00. Npr. 00 + 00 = 00. Hkrati pa je tudi 00 00 = 00. e nekemu številu prištejemo konstanto, bi priakovali, da bomo dobili neko veje število. Podobno, e številu odštejemo isto konstanto, priakujemo manjše število. V našem primeru pa dobimo obakrat enak rezultat, torej morata biti števili enaki (kar je tudi res glede na prvi bit). Množenje dveh števil A in B je tudi zelo preprosto. Tako kot v obiajni aritmetiki ga lahko tudi v aritmetiki CRC prevedemo na vsoto. Število A množimo s posameznimi biti števila B. Bite števila B beremo z desne proti levi (od najmanj pomembnega bita b 0 proti najbolj pomembnemu bitu b N ). Po vsakem množenju moramo tudi število A pomakniti za en bit v levo. Na koncu vse delne rezultate seštejemo (spomnimo, da seštevanje izvedemo z operatorjem XOR). Primer: pomnožimo števili A=0 in B=0. Prvi bit števila B je enak (gledano z desne proti levi), zato število 0 enostavno prepišemo: 0 = 0. Število A pomaknemo za en bit v levo in ga pomnožimo z drugim bitom števila B, ki je 0: 00 0 = 00000. Število A spet pomaknemo za en bit v levo in ga pomnožimo s tretjim bitom števila B: 000 = 000. Nile, ki smo jih pridobili s pomikanjem števila v levo, smo oznaili s pikami. 00 0 0000. 0.. 00 Slika 5.: Primer množenja dveh števil v aritmetiki CRC Preverimo rezultat še z množenjem polinomov. Število A lahko zapišemo kot: X 3 + X +, število B pa kot: X +. e pomnožimo (X 3 + X + ) (X + ), dobimo: X 5 + X 3 + X 3 + X + X + = X 5 + X + X +, kar je natanko naš rezultat: 00. Opozorimo še na to, kako smo izgubili oba lena X 3! Seštevanje izvedemo z operacijo XOR: X 3 X 3 = 0 X 3 = 0. Pri deljenju dveh števil A : B moramo upoštevati pravilo, da sta dve števili enaki, e se ujemata na najvišjem bitu. Najvišji bit števila B (delitelja) je vedno ena, ker vodilnih niel ne pišemo. Definirajmo deljenje. e je najvišji bit števila A

Praktina uporaba algoritmov stiskanja podatkov 37 ni, v rezultat zapišemo 0, odstranimi najvišji bit in nadaljujemo z deljenjem. e je najvišji bit števila A ena, v rezultat zapišemo, od A odštejemo B (XOR), odstranimo najvišji bit in nadaljujemo z deljenjem. V bistvu je postopek enak ronemu deljenju dveh števil, kot ga poznamo v matematiki, ob upoštevanju pravil aritmetike CRC (ni prenosa; za operacijo odštevanja uporabimo operator XOR; rezultat deljenja je, e je najvišji bit števila, ki ga delimo, enak ). Primer: delimo število A=0000 s številom B=0. (A) 0 : 0 = in ostanek je 000. (B) Najvišji bit ostanka odstranimo in pripišemo naslednji bit iz števila A: 000. 000 : 0 = 0. (C) Odstranimo najvišji bit ostanka in pripišemo naslednji bit števila A: 00. 00 : 0 = 0. (D) Odstranimo najvišji bit ostanka in pripišemo naslednji bit števila A: 0. 0 : 0 = 0. (E) Odstranimo najvišji bit ostanka in pripišemo naslednji bit števila A: 0. 0 : 0 = in ostanek je 0. (F) Odstranimo najvišji bit ostanka in pripišemo naslednji bit števila A: 0. 0 : 0 = in ostanek je 0. (G) Odstranimo najvišji bit ostanka in ker nimamo ve bitov v številu A, je deljenje zakljueno. Torej je 0000 : 0 = 000, z ostankom. (A) (B) (C) (D) (E) (F) (G) - 0 0 0 0 : 0 = 0 0 0 0 0 0 0 0 0 0 0-0 0 0-0 0 [ ] 0 0 0 Slika 5.3: Primer deljenja dveh števil v aritmetiki CRC Opozorimo, da je rezultat deljenja vedno, e je najvišji bit enak. Tako je 0 : 0 =, kot tudi 0 : 0 = in tudi 00 : 0 =. Rezultat preverimo še s polinomi: (X 5 + X + ) (X +) = X 7 + X 5 + X 3 + X + X + = X 7 + X 5 + X 3 + X + X +. Prištejmo še ostanek (X + ). Dobimo: X 7 + X 5 + X 3 + X, kar je naše število A: 0000.

Praktina uporaba algoritmov stiskanja podatkov 38 Z definiranjem operacije deljenja smo dobili osnovni postopek raunanja kode CRC, ki je enaka ostanku pri deljenju. e želimo, da bo tudi sprejemnik lahko izraunal enako kodo CRC, mora vedeti, kakšen je delitelj. Naeloma je lahko delitelj kakršenkoli, vendar je praksa pokazala, da so nekateri boljši od drugih. Ker lahko delitelj prikažemo kot polinom, nam najvišja potenca polinoma pove stopnjo delitelja. Najvekrat izbiramo delitelje stopnje šestnajst (CRC-6) ali dvaintrideset (CRC-3), predvsem zaradi lažje prilagoditve algoritma sodobnim raunalnikom. Nekateri avtorji delitelj imenujejo tudi magino število (angl. magic number). Razlog za tako poimenovanje leži v tem, da nam delitelj predstavlja kljuni podatek za raunanje kode CRC. e ne poznamo delitelja, ne moremo preveriti pravilnost sporoila s priloženo kodo CRC. Opis Magino število Razred ZIP datoteka DEBB0E3 6 CRC-3 Ethernet protokol 04CDB7 6 CRC-3 X.5 protokol 0 6 CRC-6 USB (universal serial bus) 8005 6 CRC-6 Tabela 5.: Tabela nekaterih standardnih deliteljev Opozorimo na to, da ostanek dolžine N bitov ustreza polinomu stopnje (N-). Ker pa je ostanek vedno vsaj za eno stopnjo nižji od delitelja, mora biti delitelj stopnje N, ki zahteva (N+) bitov. Vemo tudi, da je najvišji koeficient delitelja vedno ena, zato ga ne pišemo. Primer: pri CRC-3 je ostanek (naša koda CRC) dolžine 3 bitov in tako predstavlja polinom stopnje 3 s koeficienti: b 0 do b 3. Ker je delitelj vedno veji od najvejega možnega ostanka, mora biti stopnje 3, za kar potrebujemo 33 bitov: b 0 do b 3. Ker pa imajo sodobni raunalniki 3-bitne procesorje, je 33-bitno število težko uinkovito predstaviti. Vemo tudi, da je najvišji koeficient delitelja b 3 vedno, zato ga ne pišemo, preostanek pa predstavimo z 3-bitno vrednostjo. Primer: kateri polinom predstavlja magino število za ZIP datoteko? e magino število zapišemo kot binarno število, dobimo: {} 0 0 0 0 000 0000 0 00. Najvišji bit b 3, ki ga ne pišemo, smo zapisali v zavitih oklepajih. Sledi: X 3 + X 3 + X 30 + X 8 + X 7 + X 6 + X 5 + X 3 + X + X 0 + X 9 + X 7 + X 6 + X 3 + X 7 + X 6 + X 5 + X +.

Praktina uporaba algoritmov stiskanja podatkov 39 Preden se lahko lotimo raunanja kode CRC, uporabimo še eno ukano. Zaradi lažjega razumevanja bo postopek opisan za 3-bitne kode CRC in nas bo privedel do algoritma za raunanje kode CRC poljubne dolžine. S stališa raunanja bi bilo najlažje, e bi uporabljali 3-bitne delitelje. Vhodno sporoilo bi delili z deliteljem in dobili 3-bitni ostanek. Vendar bi na ta nain imeli samo 47483648 ( 3 ) razlinih kod CRC, kar je dvakrat manj, kot jih dobimo ob uporabi 33-bitnega delitelja: 49496796 ( 3 ). Torej moramo najti nain, kako 3-bitni delitelj pretvoriti v 33-bitni tako, da nas ne bo oviral pri raunanju (raunanje s 33-bitnimi vrednostmi ni ravno pisano na kožo sodobnim raunalnikom). Iz matematike vemo, da se rezultat ne spremeni, e obe strani izraza pomnožimo z isto vrednostjo. V našem primeru naj bo ta vrednost X 3, ki bo delitelj stopnje enaintrideset spremenila v delitelj stopnje dvaintrideset (v praksi delitelja ne množimo, ker je že podan kot polinom dvaintridesete stopnje). Pomnožiti moramo tudi vhodno sporoilo, kar pa je v resnici zelo lahko: na konec sporoila pripnemo niz dvaintridesetih niel. Zapišimo še formalno enabo. Naj bo naše sporoilo polinom S(x), delitelj D(x), celoštevilni rezultat deljenja S(x) : D(x) = K(x) in ostanek O(x). Tedaj lahko zapišemo: S(x) X 3 = K(x) D(x) + O(x) (5.) e vhodnemu sporoilu pripnemo ostanek (kodo CRC), dobimo na sprejemni strani: S(x) X 3 + O(x) = K(x) D(x) (5.) Ob predpostavki, da je prenos sporoila potekal brez napak, moramo na sprejemni strani dobiti kodo CRC 0, saj je vhodno sporoilo z dodanim ostankom v celoti deljivo z deliteljem D(x). Zapišimo še splošni algoritem:

Praktina uporaba algoritmov stiskanja podatkov 40. Inicializiraj delitelj: unsigned long D = predpisani delitelj. Na konec sporoila dodaj N niel, kjer je N število bitov kode CRC (množimo z X N ) 3. Inicializiraj Code na 0: unsigned long Code = 0 4. Obdelaj celotno sporoilo: while (ni konec sporoila) { zapomni si najvišji bit v Code: b N pomakni Code v levo za en bit (odstrani najvišji bit) preberi naslednji bit sporoila in ga vstavi v Code na bitu b 0 if (b N == ) Code = Code XOR D } 5. Code vsebuje ostanek: kodo CRC Morda na prvi pogled ni jasno, kako zgornji algoritem izvaja deljenje. e se spomnimo primera, ko smo rono delili dve števili, smo odšteli delitelj vsaki, ko je bil najvišji bit enak. Prav to ponemo tudi tukaj: delitelj odštejemo z operacijo XOR. e bo bralec iskal algoritem za raunanje kode CRC v literaturi ali na internetu, bo ugotovil, da ni niti malo podoben zgornjemu algoritmu. Zgornji algoritem je splošen in primeren za raunanje kakršnekoli kode CRC, vendar ima oitno slabost: obdeluje en bit naenkrat. Za uinkovito raunanje kode CRC potrebujemo algoritem, ki bo hitro vrnil rezultat tudi za zelo dolga sporoila, npr. datoteke z dolžinami nekaj MB. Ker je operacija XOR asociativna, t.j. vrstni red izvajanja operacij XOR ni pomemben, je možno algoritem popraviti tako, da naenkrat obdela cel zlog. Da proces pospešimo, si prej za vsak znak [0..55] izraunamo kodo CRC in jo shranimo v tabelo. Sledi algoritem za inicializacijo tabele: unsigned long table[55]; unsigned long D = predpisani delitelj; for (unsigned long i = 0; i < 56; i++) { unsigned long Code = i << 4; for (int j = 0; j < 8; j++) // Znak i pomaknemo v MSB // Za vsak bit znaka

Praktina uporaba algoritmov stiskanja podatkov 4 } { bool topbit = (Code & 0x80000000)!= 0; Code <<= ; // Pomaknemo se na naslednji bit if (topbit) // Najvišji bit je bil Code ^= D; // Odštejemo delitelj } table [i] = Code; // koda CRC za znak i Popravljeni algoritem za izraun kode CRC je sedaj naslednji:. Inicializiraj delitelj: unsigned long D = predpisani delitelj. Inicializiraj tabelo: table[55] tako, da uporabiš osnovni algoritem za vsak znak [0..55] 3. Na konec sporoila dodaj N niel, kjer je N število bitov kode CRC (množimo z X N ) 4. Inicializiraj Code na 0: unsigned long Code = 0 5. Obdelaj celotno sporoilo: while (ni konec sporoila) { byte top= (Code >> 4) & 0xFF; // Najvišji byte v Code Code = (Code << 8); // Odstrani najvišji byte v Code Code = Code naslednji zlog sporoila; // Naslednji zlog sporoila Code = Code XOR table[top]; } 6. Code vsebuje ostanek: kodo CRC V jeziku C++ celotno vsebino zanke while obiajno zapišemo v enem stavku, pri emer je *p kazalec na naše vhodno sporoilo, operator ^ pa operator XOR: Code = ((Code << 8) *p++) ^ table[(code >> 4) & 0xFF] oziroma Code = ((Code << 8) *p++) ^ table[(code >> 4)] eprav zgornji algoritem deluje popolnoma pravilno in bi ga težko še bolj strnili, pa so nekateri avtorji našli še nekaj prostora za optimizacijo. Na zaetku je Code enak 0 (00000000 6 ), zato potrebujemo štiri prazne cikle, preden pridemo do zlogov sporoila (spomnimo, da v vsaki ponovitvi zanke odstranimo najvišji zlog). Druga slabost je, da moramo sporoilo najprej dopolniti z nilami na koncu:

Praktina uporaba algoritmov stiskanja podatkov 4 množenje z X N. Spet se izkaže, da sta oba koraka nepotrebna, e stavek znotraj zanke while malo popravimo: Code = (Code << 8) ^ table[(code >> 4) ^ *p++] Zgornji stavek bomo najpogosteje sreali v literaturi, vasih pa tudi obrnjeno razliico. e delitelj obrnemo, tako da ima na levi strani najmanj pomemben bit b 0, na desni pa najbolj pomembnega b N, je možno zgornji stavek še malo optimizirati: Code = (Code >> 8) ^ table[code ^ *p++] Ker je najbolj pomemben zlog sedaj na desni, moramo bite pomikati v desno. Prednost pa je v tem, da ne potrebujemo nobenega pomika, da pridemo do najvišjega zloga (prej: Code >> 4). Kadar uporabljamo obrnjeno razliico algoritma, moramo tudi pri raunanju tabele upoštevati pomik bitov v desno. Zapišimo konno verzijo algoritma:. Inicializiraj delitelj: unsigned long D = predpisani delitelj. Inicializiraj tabelo: table[55] tako, da uporabiš osnovni algoritem za vsak znak [0..55] 3. Inicializiraj Code na 0: unsigned long Code = 0 4. Obdelaj celotno sporoilo: while (ni konec sporoila) Code = (Code << 8) ^ table[(code >> 4) ^ *p++] 5. Code vsebuje ostanek: kodo CRC 6 IMAPI IMAPI (angl. Image Mastering API) je programski vmesnik, ki omogoa zapisovanje podatkov na medije CD in DVD. Programski vmesnik je na voljo od operacijskega sistema Windows XP dalje, za starejše operacijske sisteme pa funkcionalnost ni podprta. Obstajata dve razliici:

Praktina uporaba algoritmov stiskanja podatkov 43 IMAPI.0: je na voljo v operacijskih sistemih Windows XP in Windows Server 003. Omogoa zapisovanje na medije CD, ne pa tudi na medije DVD. IMAPI.0: na voljo v operacijskih sistemih Windows Vista in Windows Server 008. Omogoa zapisovanje na medije CD in DVD. Za operacijska sistema Windows XP in Windows Server 003 obstajata dodatka, ki omogoa enako funkcionalnost, vendar ju je potrebno posebej namestiti. IMAPI.0 podpira zapis na naslednje vrste optinih medijev: CD-R, CD-RW, DVD-R, DVD+R, DVD-RW, DVD+RW, DVD-RAM ter dvoplastni DVD-R in DVD+R. Prav tako podpira naslednje oblike zapisa: ISO 9660, Joliet in UDF. Struktura datotenega sistema na CD-ju ali DVD-ju omogoa, da lahko imamo vse tri hkrati na istem mediju. Program za predvajanje potem sam izbere tisto obliko, ki mu najbolj ustreza. To je možno zaradi tega, ker so razlina samo kazala, ki pripadajo posamezni obliki zapisa, vsebina (npr. glasba, program, slike itd.) pa je enaka. Kazalo vsebuje seznam datotek, ki so shranjene na mediju. V podrobnosti standardov se na tem mestu ne bomo spušali, bralec lahko podroben opis najde v [9] in [0]. 6. Znani problemi e želimo uporabljati IMAPI.0 v okolju Windows XP, moramo ustrezen dodatek posebej namestiti. Dodatek se dobi na Microsoftovih straneh za podporo in se imenuje WindowsXP-KB9376-v-x86-ENU.exe. Ob namestitvi se v mapo C:\Windows\System3\ shranita dve sistemski knjižnici: imapi.dll in imapifs.dll, vse javno vidne komponente iz obeh knjižnic pa se zapišejo v sistemski register. Za IMAPI ne obstaja programska knjižnica (angl. type library), zato programiranje z IMAPI ni možno v jezikih, ki zahtevajo strogo deklaracijo spremenljivk. Razlog je zelo preprost: ker tipov ni možno uvoziti, jih tudi ni možno uporabljati. Izjema je programski jezik C++. Za C++ so na voljo datoteke.h, kjer so

Praktina uporaba algoritmov stiskanja podatkov 44 deklaracije vseh vmesnikov: imapi.h in imapifs.h. Naeloma bi lahko IMAPI programirali tudi v ogrodju.net, npr. v programskem jeziku C#. V ogrodju.net je z dodajanjem povezav na zunanje knjižnice (angl. Add reference) možno uvoziti obe sistemski knjižnici: imapi.dll in imapifs.dll. Ob uvozu se kreira dodatni vmesnik, ki služi zgolj za komunikacijo med kodo, napisano v ogrodju.net (angl. managed code) in kodo, ki pripada komponentam IMAPI. Ker pa ogrodje.net zahteva strogo loevanje razredov po imenskih podrojih, se pri uvozu glede na knjižnico vmesniki razdelijo na dve imenski podroji: IMAPI in IMAPIFS. Veina vmesnikov in njihovih funkcij deluje dobro. Težave nastanejo, kadar moramo posredovati vmesnik iz enega imenskega podroja v drugega. Takrat prevajalnik javi napako, eprav napake v bistvu ni. Primer: e želimo zapisati podatke na CD, moramo v vmesniku IDiscFormatData klicati metodo Write(IStream* stream), pri emer je stream binarna datoteka. Binarno datoteko tvori drug vmesnik IFileSystemImage preko metode CreateResultImage(). Ker sta oba vmesnika vsak v svojem imenskem podroju, Write() zahteva, da je stream tipa IMAPI.IStream, IFileSystemImage pa vraa IMAPIFS.IStream. Vse probleme je možno rešiti tako, da IMAPI programiramo v jeziku C++. Ker pa želimo programirati v ogrodju.net, je najbolje, da v jeziku C++ napišemo komponento, ki bo služila kot vmesnik med IMAPI in programom, napisanim v C# ali Visual Basic.Net. V tem vmesniku bomo definirali metode, ki nam bodo posredno omogoale dostop do funkcij IMAPI. Ena izmed metod komuniciranja med razlinimi aplikacijami v okolju Windows je uporaba OLE (angl. Object Linking And Embedding). OLE omogoa urejanje dokumentov, ki so nastali v drugih aplikacijah, npr. v svoji aplikaciji lahko omogoimo urejanje Excelove preglednice. OLE združuje dve vrsti objektov: tiste, ki imajo grafini vmesnik in jih je možno videti na zaslonu (v obliki komponent ActiveX) in tiste, ki zagotavljajo zgolj neko funkcionalnost in grafinega vmesnika ne potrebujejo (v obliki komponent COM). OLE ima mnogo prednosti, ima pa tudi zelo veliko slabost. e želimo uporabiti katerikoli objekt OLE, ga moramo najprej

Praktina uporaba algoritmov stiskanja podatkov 45 registrirati (vpisati v sistemski register raunalnika). Obiajno registracijo opravi namestitveni program, možno pa jo je izvesti tudi rono. V mapi C:\Windows\System3\ se nahaja program regsvr3.exe, ki mu je potrebno posredovati ime knjižnice, ki jo želimo registrirati. Primer: e se komponenta nahaja v knjižnici c:\programabc\abc.dll, jo rono registriramo z ukazom: c:\windows\system3\regsvr3.exe c:\programabc\abc.dll. Za dostop do funkcionalnosti IMAPI ne potrebujemo grafinega vmesnika, zato bomo napisali komponento COM. V jeziku C++ je komponente COM najlaže napisati s pomojo knjižnice ATL (angl. Active Template Library). ATL vsebuje izbran nabor generinih razredov (isti razred lahko uporabimo nad razlinimi tipi podatkov). Zaradi tega je kode malo in se izvaja hitro. 6. Vmesniki IMAPI IMAPI omogoa zelo natanno kontrolo nad procesom zapisovanja podatkov na medije CD/DVD. Vsebuje osemintrideset vmesnikov, od tega je za osnovni zapis potrebnih šest: IDiscMaster: dostop do osnovnih podatkov o namešenih pogonih CD/DVD (število pogonov in enolina oznaka vsakega pogona). IDiscRecorder: predstavlja fizini pogon CD/DVD. Omogoa dostop do informacij o pogonu (ime, proizvajalec, rka pogona, lastnosti itd.) ter odpiranje in zapiranje pogona. IFileSystemImage: pretvori strukturo map in datotek, ki jih želimo zapisati na medij CD/DVD, v obliko, primerno za zapis - slika zapisa. IFileSystemImageResult: pretvorjena oblika za zapis. IFsiDirectoryItem: predstavlja mapo in datoteke v njej (podobno strukturi map in datotek na disku). IDiscFormatData: zapiše podatke na medij CD/DVD.

Praktina uporaba algoritmov stiskanja podatkov 46 IDiscMaster: je vmesnik za dostop do podatkov o namešenih pogonih CD/DVD. Kreiramo ga z ukazom: CComPtr<IDiscMaster> dm; HRESULT hr = dm.cocreateinstance(clsid_msftdiscmaster); (a) get_count(): vrne število namešenih pogonov CD/DVD. HRESULT get_count ( [out] LONG* value // vrne št. Pogonov ); (b) get_item(): vrne enolino oznako pogona (ID). HRESULT get_item ( [in] LONG index, // zaporedna št. Pogona, >= 0 [out] BSTR* value // vrne id pogona ); IDiscRecorder: je vmesnik, ki predstavlja posamezni fizini pogon CD/DVD. Kreiramo ga z ukazom: CcomPtr<IdiscRecorder> dr; HRESULT hr = dr.cocreateinstance(clsid_msftdiscrecorder); (a) InitializeDiscRecorder():poveže vmesnik s fizinim pogonom CD/DVD. HRESULT InitializeDiscRecorder ( [in] BSTR id // ID pogona (ki ga vrne IdiscMaster) ); IFileSystemImage: vmesnik, ki pretvori mape in datoteke, ki jih želimo zapisati na medij CD/DVD, v obliko, primerno za zapis. Kreiramo ga z ukazom: CcomPtr<IfileSystemImage> im; HRESULT hr = im.cocreateinstance(clsid_msftfilesystemimage);

Praktina uporaba algoritmov stiskanja podatkov 47 (a) get_root(): vrne korensko mapo. V to mapo dodajamo ostale mape in datoteke, ki jih želimo zapisati na medij CD/DVD. HRESULT get_root ( [out] IfsiDirectoryItem** dir // vrne korensko mapo ); (b) SetMaxMediaBlocksFromDevice(): vmesnik vpraša zapisovalnik po številu prostih blokov. HRESULT SetMaxMediaBlocksFromDevice ( [in] IdiscRecorder* rec // zapisovalnik ); (c) put_filesystemtocreate(): povemo, katere oblike zapisa želimo kreirati: ISO 9660, Joliet ali UDF. Možne so tudi kombinacije vseh treh. FsiFileSystems je naštevalni tip in je definiran: FsiFileSystemNone=0, FsiFileSystemISO9660=, FsiFileSystemJoliet=, FsiFileSystemUDF=4, FsiFileSystemUnknown=0x40000000. HRESULT put_filesystemstocreate ( [in] FsiFileSystems value // ISO9660, Joliet, UDF ); (d) put_volumename(): povemo ime medija CD/DVD. Ime je vidno v Raziskovalcu, kadar je medij vstavljen v pogon. HRESULT put_volumename ( [in] BSTR name // ime medija ); (e) CreateResultImage(): pretvori mape in datoteke v obliko, primerno za zapis. HRESULT CreateResultImage ( [out] IfileSystemImageResult ** res // vrne obliko, primerno za zapis );

Praktina uporaba algoritmov stiskanja podatkov 48 IFileSystemImageResult: vmesnik, ki omogoa dostop do binarne datoteke, ki se bo zapisala na medij CD/DVD. Datoteka je že v obliki, primerni za zapis. Objekta ne moremo kreirati, dobimo ga kot rezultat metode CreateResultImage(). (a) get_imagestream(): vrne binarno datoteko, do katere dostopamo preko vmesnika Istream. HRESULT get_imagestream ( [out] Istream** stream // vrne binarno datoteko ); IFsiDirectoryItem: vmesnik, ki omogoa gradnjo datotenega sistema (map in datotek), ki jih bomo zapisali na medij CD/DVD. Vmesnika ni mogoe kreirati, dobimo ga kot rezultat razlinih metod. (a) AddTree(): v IfsiDirectoryItem doda celotno mapo, z vsemi podmapami in datotekami. HRESULT AddTree ( [in] BSTR path, // pot do mape [in] BOOL include // TRUE, e naj se mapa doda kot ); // podmapa (b) AddDirectory(): v IFsiDirectoryItem doda mapo. HRESULT AddDirectory ( [in] BSTR path ); // ime mape (c) AddFile(): v IFsiDirectoryItem doda datoteko. HRESULT AddFile ( [in] BSTR path, [in] IStream* stream ); // pot do mape // datoteka

Praktina uporaba algoritmov stiskanja podatkov 49 IDiscFormatData: vmesnik, ki omogoa zapis. Kreiramo ga z ukazom: CComPtr<IDiscFormatData> dw; HRESULT hr = dw.cocreateinstance(clsid_msftdiscformatdata); (a) Write(): zapiše podatke na medij CD/DVD. HRESULT Write ( [in] IStream* stream ); // datoteka, ki jo želimo zapisati (b) put_clientname(): ime programa, ki dostopa do zapisovalnika. Ime se mora ujemati z imenom programa zaradi tega, ker se pri zapisovanju zahteva ekskluzivni dostop do zapisovalnika (eprav Microsoft trdi, da je lahko ime kakršnokoli, se izkaže, da mora biti enako imenu programa, drugae ekskluzivni dostop do zapisovalnika ni možen). HRESULT put_clientname ( [in] BSTR name // ime programa ); (c) put_recorder(): povežemo zapisovalnik s fizinim pogonom CD/DVD. HRESULT put_recorder ( [in] IDiscRecorder* rec // fizini pogon CD/DVD ); Primer: preprostega programa, ki bo zapisal podatke na CD. Da bo primer bolj pregleden, bomo zapisali zgolj osnovni postopek, brez obravnave napak, deklaracij metod itd. Preden nadaljujemo, moramo v projektu v seznam datotek.h (»Header files«) dodati datoteki imapi.h in imapifs.h (e imamo Windows XP in smo namestili dodatek, bi jih morali najti v mapi: C:\Program Files\Microsoft SDKs\Windows\v6.\Include\). #include»imapi.h«#include»imapifs.h«hresult hr=s_ok; CComBSTR volname("test_atl"); CComBSTR path("c:\\temp\\slike"); CComBSTR client(theapp.m_pszappname); CComBSTR id;

Praktina uporaba algoritmov stiskanja podatkov 50 CComPtr<IDiscMaster> dm; CComPtr<IDiscRecorder> dr; CComPtr<IFileSystemImage> im; CComPtr<IDiscFormatData> dw; CComPtr<IFsiDirectoryItem> root=null; CComPtr<IFileSystemImageResult> res=null; CComPtr<IStream> stream=null; hr=dm.cocreateinstance(clsid_msftdiscmaster); hr=dr.cocreateinstance(clsid_msftdiscrecorder); hr=im.cocreateinstance(clsid_msftfilesystemimage); hr=dw.cocreateinstance(clsid_msftdiscformatdata); hr=dm->get_item(0,&id); hr=dr->initializediscrecorder(id); hr=dw->put_recorder(dr); hr=dw->put_clientname(client); hr=im->put_volumename(volname); hr=im->setmaxmediablocksfromdevice(dr); hr=im->put_filesystemstocreate(fsifilesystems::fsifilesystemiso9660); hr=im->get_root(&root); hr=root->addtree(path,true); hr=im->createresultimage(&res); hr=res->get_imagestream(&stream); hr=dw->write(stream);

Praktina uporaba algoritmov stiskanja podatkov 5 7 PROGRAM Zahteve programa so že od samega zaetka bile, da mora podpirati ve razlinih opravil: arhiviranje, obnovitev podatkov iz arhiva in zapisovanje na medije CD/DVD. Upoštevali smo tudi možnost, da bo potrebno program neko nadgraditi in dodati funkcionalnost, ki trenutno ni podprta. Zato je program zgrajen modularno. 7. Razredni diagrami Strukturo smo si zamislili tako, da ima vsako opravilo svoj nabor razredov. Razredi so razdeljeni po imenskih podrojih (angl. Namespace). Ker se nahajajo v loeni knjižnici, imenovani DipZipClasses, jih lahko enostavno vkljuimo v druge projekte. To je možno tudi zaradi tega, ker smo se pri razvoju strogo držali pravila, da morajo razredi predstavljati zgolj programsko logiko. Na ta nain smo dosegli neodvisnost med funkcionalnim in predstavitvenim delom programa. DipZipClasses Docs Document DocumentRoot DocumentFolder DocumentItem DocumentItemProgram DocumentItemArchive DocumentItemDearchive DocumentItemBackup DocumentItemBackupSettings Zip ZipArchive ZipCodec ZipFileHeader ZipLocalFileHeader ZipEndOfCentralDir Burn BurnManager Slika 7..: Imenska podroja in razredi knjižnice DipZipClasses

Praktina uporaba algoritmov stiskanja podatkov 5 Imensko podroje»docs«: program shranjuje nastavitve v datoteko (dokument). Razredi v imenskem podroju»docs«nam omogoajo ravnanje z dokumenti: odpiranje, shranjevanje in vzpostavljanje hierarhine strukture dokumenta. Ker nam služijo zgolj za predstavitev in urejanje opravil, jih na tem mestu ne bomo podrobneje opisovali. Slika 7..: Razredni diagram (dokument)

Praktina uporaba algoritmov stiskanja podatkov 53 Imensko podroje»zip«: za kreiranje oz. odpiranje arhivskih datotek Zip uporabljamo razred ZipArchive. Ostali razredi so pomožni in predstavljajo posamezne gradnike datoteke ZIP. Slika 7..3: Razredni diagram (arhiviranje) Programski vmesnik razreda ZipArchive: Public Property ExtractTo() As String Mapa (celotna pot), kamor se bodo shranile datoteke pri obnovitvi podatkov. Public Property ExtractWhat() As String Ime datoteke ali vzorec, ki doloa, katere datoteke bodo obnovljene iz arhiva ZIP. Privzeta vrednost je *.* za obnovitev vseh datotek v arhivu.

Praktina uporaba algoritmov stiskanja podatkov 54 Public Property Filename() As String Ime (celotna pot) datoteke ZIP. Public ReadOnly Property FilenameVersion() As String Vrne ime datoteke ZIP z dodano verzijo datoteke. e pri arhiviranju datoteka ZIP že obstaja in je ne smemo prepisati, se doloi novo ime tako, da se na konec prvotnega imena pripne verzija. Verzije se oznaujejo z A, B, C itd. Public Property Overwrite() As Boolean Nastavitev, ali lahko pri arhiviranju datoteko ZIP prepišemo, e že obstaja. Vrednost TRUE doloa, da se datoteka prepiše. Privzeta vrednost je FALSE; datoteke ne smemo prepisati. Public Sub AddArchiveCopy(ByVal Path As String) Doda mapo v seznam map za dodatne kopije arhivske datoteke. Po arhiviranju je možno shraniti dodatno kopijo arhivske datoteke v razline mape, npr. na drug disk ali raunalnik. Parametri: Path: mapa (celotna pot), kamor naj se po arhiviranju shrani dodatna kopija arhivske datoteke. Public Sub AddExclude(ByVal Path As String, ByVal Subfolders As Boolean) V seznam doda ime datoteke ali vzorec, ki pove, katere datoteke naj program pri arhiviranju preskoi. Parametri: Path: ime datoteke ali vzorec, npr. C:\Programi\*.exe Subfolders: vrednost TRUE doloa, da program preiše tudi vse podmape Public Sub AddInclude(ByVal Path As String, ByVal Subfolders As Boolean) V seznam doda ime datoteke ali vzorec, ki pove, katere datoteke naj program arhivira. Parametri: Path: ime datoteke ali vzorec, npr. C:\Programi\*.*

Praktina uporaba algoritmov stiskanja podatkov 55 Subfolders: vrednost TRUE doloa, da program preiše tudi vse podmape Public Function Create() As Boolean Kreira datoteko ZIP. e je arhiviranje potekalo brez napak, vrne vrednost TRUE, drugae FALSE. Public Function Extract() As Boolean Obnovi datoteke iz arhiva ZIP. e so bile vse datoteke v arhivu uspešno obnovljene, vrne vrednost TRUE, drugae FALSE. Primer: opišimo, kako s programom izvedemo arhiviranje. Arhivirati želimo datoteko C:\FERI\Diploma\Diploma.doc in podatke v mapi C:\Programi z vsemi podmapami, vendar ne želimo arhivirati programov. Arhivska datoteka se bo imenovala Podatki_009068.ZIP in jo želimo kreirati v mapi C:\Arhiv. Dodatno kopijo arhivske datoteke želimo imeti v mapi F:\Backup, ki se nahaja na izmenljivem disku. Dim Zip As ZipArchive=New ZipArchive Zip.Filename="C:\Arhiv\Podatki_009068.zip" Zip.AddArchiveCopy("F:\Backup\") Zip.AddInclude("C:\FERI\Diploma\Diploma.doc", False) Zip.AddInclude("C:\Programi\*.*", True) Zip.AddExclude("C:\Programi\*.exe", True) Zip.Create() Za obnovitev datotek iz arhivske datoteke v mapo C:\Temp pišemo: Dim Zip As ZipArchive=New ZipArchive Zip.Filename="C:\Arhiv\Podatki_009068.zip" Zip.ExtractWhat="*.*" Zip.ExtractTo="C:\Temp\" Zip.Overwrite=True Zip.Extract() Imensko podroje»burn«: zaradi znanih problemov pri uvozu knjižnic IMAPI v ogrodje.net smo morali dostop do vmesnikov IMAPI zagotoviti v jeziku C++. Napisali smo komponento ATL COM, ki jo lahko uvozimo v ogrodje.net in preko nje posredno omogoili funkcionalnost zapisovanja na medije CD/DVD. Razred BurnManager olajša komunikacijo med programom in komponento ATL COM.

Praktina uporaba algoritmov stiskanja podatkov 56 Slika 7..4: Razredni diagram (zapisovanje na medij CD/DVD) Programski vmesnik razreda BurnManager: Public ReadOnly Property LastError() As String Vrne opis napake. IMAPI vraa kodo napake, zato smo v komponenti ATL COM poskrbeli za uporabniku bolj prijazen opis napake. Public ReadOnly Property ListOfRejectedFiles() As List(Of DipZipClasses.Docs.DocumentFile) Vrne seznam zavrnjenih datotek. Pri dodajanju datotek v sliko IMAPI zapisa se lahko zgodi, da je velikost datoteke veja kot pa je prostora na mediju CD/DVD. Public Property SelectedRecorder() As Integer Zaporedna številka pogona CD/DVD, ki bo uporabljen pri zapisovanju. IMAPI dostopa do pogonov preko številke pogona. Public Property SessionLabel() As String Oznaka seje zapisovanja. Ker je omogoeno vekratno snemanje, lahko ima vsako seja svojo oznako. Oznaka je vidna v Raziskovalcu, ko vstavimo medij CD/DVD v pogon. Public Sub AddFile(ByVal Path As String, Optional ByVal Subfolders As Boolean = False) V seznam datotek, ki akajo na zapis, doda ime datoteke. Parametri:

Praktina uporaba algoritmov stiskanja podatkov 57 Path: ime datoteke (polna pot) Subfolders: vrednost TRUE doloa, da program preiše tudi vse podmape Public Function Burn() As Boolean Zapiše datoteke na medij CD/DVD. Public Sub Clear() Pripravi BurnManager na novo sejo zapisovanja. Public Function ListOfBurnDevices() As List(Of String) Vrne seznam imen vseh pogonov CD/DVD, ki omogoajo zapisovanje. Primer: opišimo, kako s programom izvedemo zapisovanje na medij CD/DVD. Zapisali bomo arhivsko datoteko C:\Arhiv\Podatki_009068.ZIP in sliko C:\Slike\LogarskaDolina.jpg. Ime seje zapisovanja naj bo Podatki. Dim Burner As BurnManager=New BurnManager Burner.Clear() Burner.SelectedRecorder=0 Burner.SessionLabel="Podatki" Burner.AddFile("C:\Arhiv\Podatki_009068.zip") Burner.AddFile("C:\Slike\LogarskaDolina.jpg") Burner.Burn() 7. Predstavitev delovanja programa Pri razvoju programa smo najveji poudarek namenili enostavnosti uporabe. Program je smiselno razdeljen v štiri skupine opravil: zagon programov, arhiviranje, obnovitev podatkov iz arhiva in kopiranje na CD/DVD. Vsaka skupina je predstavljena z velikim gumbom. Kratek opis daje uporabniku namig glede namembnosti. Vse nastavitve je možno shraniti v datoteko (dokument). Program si zapomni zadnji odprt dokument in ga ob naslednjem zagonu samodejno prebere. S tem smo manj vešim uporabnikom omogoili, da lahko takoj zanejo z delom. Bolj

Praktina uporaba algoritmov stiskanja podatkov 58 izkušeni uporabniki pa imajo na voljo tudi ukaze za ravnanje z dokumenti: kreiranje novega dokumenta, odpiranje že obstojeega dokumenta, shranjevanje sprememb in shranjevanje dokumenta pod drugim imenom (kopija dokumenta). Ime dokumenta je vidno v naslovni vrstici okna. Slika 7..: Pozdravno okno programa Dokument je možno organizirati v sistem map in podmap, ki jih lahko uporabnik poljubno odpira in s tem doseže vejo preglednost. Uporabniški vmesnik je, ne glede na opravilo, vedno enak in ga je enostavno osvojiti. Na levi strani okna so prikazane mape, na desni pa vsa opravila, ki se nahajajo v izbrani mapi. Za lažje prepoznavanje vsako opravilo prikaže ime in kratek opis. Pri programih je dodatno prikazana še ikona programa. Opis se z vejimi rkami izpiše tudi v statusni vrstici na dnu okna, e potujemo s kazalcem miške preko opravila. Opravilo poženemo z dvoklikom miške ali z izbiro iz kontekstnega menuja.

Praktina uporaba algoritmov stiskanja podatkov 59 Slika 7..: Okno z opravili za zagon programov Izbrana mapa oz. vsa izbrana opravila so obarvana oranžno in se jasno loijo od ostalih elementov. Medtem ko lahko izberemo samo posamezno mapo, pri opravilih te omejitve ni. Izbiranje ve opravil je v skladu s standardi v okolju Windows: s tipko SHIFT in klikom miške za izbiranje ve zaporednih elementov hkrati. s tipko CTRL in klikom miške za izbiranje posameznih elementov. Na vrhu okna smo dodali priroen menu, ki uporabniku omogoa, da od koderkoli doseže vse funkcije programa z enim klikom miške. Tako mu ni treba nazaj na prvo stran, da bi zamenjal opravilo. Zagon programov in datotek: omogoa hiter dostop do najpogosteje uporabljanih programov in datotek. Program/datoteka se odpre v novem oknu. Arhiviranje podatkov: na enostaven nain arhiviramo podatke (datoteke), ne da

Praktina uporaba algoritmov stiskanja podatkov 60 bi pri tem morali poznati podrobnosti. Napredek arhiviranja lahko opazujemo v novem oknu. Le-ta prikazuje ime datoteke, ki se trenutno arhivira ter procent konanega dela. Za bolj nazorno predstavitev se procent konanega dela izrisuje tudi grafino. Slika 7..3: Napredek arhiviranja Arhiviranje je možno med izvajanjem tudi preklicati, kar pa ne pomeni, da bo arhivska datoteka neuporabna. Program bo samo prej zakljuil z delom in izpisal opozorilo, da vse datoteke niso bile arhivirane. Dodatno vrednost predstavlja samodejno arhiviranje, ki ga je možno pognati ob vnaprej doloenem asu s pomojo Razporejevalnika opravil (sistemski program v okolju Windows). Recimo, da želimo arhiviranje izvajati vsak dan ob :00. Najprej moramo v lastnostih arhiviranja oznaiti»omogoi samodejni zagon«in pod»oznaka za samodejni zagon«vpisati oznako, npr. dnevno. Nato v Razporejevalniku opravil definiramo novo opravilo, ki zažene program vsak dan ob :00. Kot parameter ob zagonu programa podamo /a:dnevno. Obnovitev podatkov iz arhiva: opravilo prekrije trenutne podatke s starejšo razliico, zato moramo biti pri uporabi te izbire še posebej pazljivi. Priporoamo arhiviranje trenutnih podatkov in šele nato obnovitev. Ob zagonu opravila moramo najprej izbrati arhivsko datoteko, iz katere bomo obnavljali podatke. Za lažje iskanje so arhivske datoteke organizirane po letu in

Praktina uporaba algoritmov stiskanja podatkov 6 mesecu arhiviranja. Izbrati je možno samo eno arhivsko datoteko. Ciljno mapo lahko pred prietkom obnovitve spremenimo, kar nam pride prav, e želimo podatke obnoviti v zaasno mapo, npr. da podatke najprej pregledamo. Za lažji vnos uporabimo gumb»prebrskaj«. Slika 7..4: Obnovitev podatkov (izbira arhivske datoteke) Ob potrditvi lahko napredek opazujemo v novem oknu. Napredek obnovitve prikazuje ime datoteke, ki se trenutno obnavlja, ter procent konanega dela. Obnovitev podatkov je možno med izvajanjem tudi preklicati. V tem primeru bodo obnovljene samo datoteke do preklica. Zapisovanje na medij CD/DVD: programi, ki omogoajo zapis na medije CD/DVD so za veino uporabnikov praviloma preve zahtevni in jih zato ne uporabljajo. Zato smo se odloili, da postopek kar se da poenostavimo. Ob zagonu opravila najprej izberemo vse arhivske datoteke, ki jih želimo zapisati na medij CD/DVD. Za lažje iskanje so arhivske datoteke organizirane po letu in mesecu arhiviranja.

Praktina uporaba algoritmov stiskanja podatkov 6 Slika 7..5: Kopiranje na CD/DVD (izbira arhivske datoteke) Preden zanemo z zapisovanjem, moramo izbrati še osnovne nastavitve zapisa. Program predlaga najbolj verjetne vrednosti, tako da v veini primerov predlagane vrednosti samo potrdimo: CD/DVD zapisovalnik izbiramo, e jih je namešenih ve. Program predlaga prvega, ki ga najde. Ker je omogoeno vekratno snemanje, lahko za vsako sejo zapisovanja podamo drugo oznako. Oznaka je vidna v Raziskovalcu, ko vstavimo medij CD/DVD v pogon. Veina programov zna prikazati samo vsebino zadnje seje zapisovanja. Privzeta oznaka se sestoji iz trenutnega datuma. Seznam arhivskih datotek smo pridobili z izbiro v prejšnjem koraku. Pred zapisom imamo možnost, da katero od datotek izloimo, ne da bi morali nazaj na izbiro. Statusna vrstica prikazuje opis ter grafini prikaz napredka.

Praktina uporaba algoritmov stiskanja podatkov 63 Slika 7..6: Zapisovanje na medij CD/DVD (prikaz napredka) Postopek zapisovanja je možno med izvajanjem tudi preklicati, vendar tega ne priporoamo, ker bo medij CD/DVD neuporaben. Razlog je v samem postopku zapisovanja. Pred zapisovanjem se kreira binarna slika zapisa, na zaetku katere se nahaja kazalo, ki mu sledijo datoteke. Slika se potem v enem kosu zapiše na medij CD/DVD. e postopek vmes prekinemo, bomo zapisali nepopolno kazalo ali pa bo le-to kazalo na datoteke, ki niso bile zapisane. Tako bodo v najboljšem primeru datoteke vidne v Raziskovalcu, vendar do njih ne bo možno dostopati. 7.3 Parametri za samodejni zagon e program poženemo brez parametrov, preidemo v interaktivni nain, kjer sami komuniciramo z uporabniškim vmesnikom: izbiramo vrsto opravila, rono zaganjamo opravila itd. Program omogoa tudi izvajanje v ozadju, brez uporabniškega vmesnika. V ta namen moramo v ukazni vrstici podati stikala, ki programu povedo, kaj naj stori. Stikalo mora biti podano v obliki /x:vrednost, kjer x predstavlja oznako akcije. Možno je podati ve stikal hkrati. Stikala, ki jih program prepoznava so: