5. Järjendid ja for-tsükkel

Informaatika õppelehekülg

5.1. JÄRJEND

Seni on meil programmides erinevate andmete hoidmiseks olnud eraldi muutujad. Paljude ülesannete puhul on vägagi mõistlik teatud andmeid koos käsitleda – teatud andmestruktuuridena. Erinevates programmeerimiskeeltes on selle jaoks mõnevõrra erinevad vahendid. Ka konkreetses programmeerimiskeeles võib olla mitmeid võimalusi, on Pythoniski. Pythoni üheks põhiliseks andmestruktuuriks on järjend ehk list (ingl list). Siinkohal tuleb märkida, et erinevate programmeerimiskeelte ja isegi erinevate materjalide puhul võib terminoloogia erineda. Meie peame siin järjendit ja listi sünonüümideks, mujal ei pruugi see nii olla.

Järjend koosneb elementidest, mis loetletakse nurksulgudes üksteisest komadega eraldatutena. Näiteks

Järjendis võib olla korduvaid elemente, näiteks järjendis temperatuurid on 4 kaks korda. Eeltoodud järjendites on esimeses ainult sõned ja teises ainult täisarvud. Tegelikult võivad Pythonis ühe järjendi elemendid olla ka erinevat tüüpi, aga tavaliselt me seda võimalust ei kasuta. Järjendeid võime liigitada nende elementide tüüpide järgi. Muutujas nädalapäevad on meil nüüd siis sõnejärjend ja muutujas temperatuurid täisarvujärjend.

Vaatame, mis tüüpi näitab Python ise muutuja temperatuurid puhul.

5.1.2. MÕNED OPERATSIOONID. INDEKSID

Järgmise programmis on demonstreeritud mõningaid järjendiga seotud operatsioone.

Mõnevõrra üllatav võib tunduda see, et nädalapäevad[1] ei anna meile esimest elementi, vaid hoopis teise. Nimelt tavatsetakse programmeerimises nummerdamist alustada nullist. Tõepoolest

annab (argimõttes) esimese elemendi. Seega tuleb olla väga tähelepanelik, kas jutt on argine või programmeerimisest. Selguse mõttes räägime siis pigem elemendi indeksist, näiteks element indeksiga 1. Nagu juba nägime märgitakse indeks nurksulgudesse.

Tegelikult ei alga ka tavaelus nummerdamine alati ühest. Näiteks on mõnedes rongijaamades platvorm 0 (Londoni King’s Cross, Cardiffi keskjaam). (Eks King’s Crossi jaamas ole ka muidugi platvorm 9 3/4.)

Kuna loendamine algab nullist, siis viimase elemendi indeks on ühe võrra väiksem järjendi pikkusest, järjendi nädalapäevad puhul siis 6, sest elemente on 7.

Kui minna “üle piiri”, kasutades sellist indeksit, millele vastavat elementi pole, siis ilmub veateade IndexError: list index out of range.

Pythonis on tõepoolest võimalus kasutada negatiivseid indekseid. Tegelikult me oleme seda juba kasutanud vihjes Leedu perekonnanimede ülesande juures: Viimase tähe kontrollimiseks sobib nimi[-1] == "e".

Tookord oli tegemist sõnega, mida aga saabki käsitleda sümbolite jadana. Nii ongi väga mitmed (siiski mitte kõik) operatsioonid võimalikud nii järjendite kui sõnedega. (Tegelikult veel teistegi andmestruktuuridega, mida selles kursuses üldiselt ei käsitleta.)

5.1.3. VIILUTAMINE

Leedu perenimede ülesande juures oli veel kirjas, et kahe viimase tähe kontrollimiseks saab kasutada näiteks võrdlemist nimi[-2:] == "ne". Tegemist on viilutamisega, mis toimib nii järjendite kui sõnede puhul ja millega saame vastavalt alamjärjendi või alamsõne. Vaatleme viilutamise võimalusi järgmise programmi abil, kus “noa all” on (antud juhul ühesümboliliste) sõnede järjend. Meelega on sama tulemuse saamiseks kasutatud erinevaid võimalusi.

Enne koolonit kirjutatakse indeks, millest alates tuleb elemente kopeerida, ja kooloni järele indeks, mille juures tuleb kopeerimine lõpetada (selle indeksiga element jääb tulemusest välja). Kui algav indeks kirjutamata jätta, siis alustatakse järjendi (sõne) algusest. Kui lõpetav indeks kirjutamata jätta, siis kopeeritakse kuni järjendi (sõne) lõpuni (viimane element kaasaarvatud).

Järgmises näites viilutatakse erinevaid sõnesid – nii neid, mis on muutujale väärtuseks antud, kui ka neid, mis pole.

5.1.4. VEEL OPERATSIOONIDEST

Toome lõpetuseks tabeli, milles on nii juba mainitud kui mainimata võimalusi.

AvaldisVäärtusKommentaar
len([2, 1, 4, 3, -5])5Elementide arv
min([2, 1, 4, 3])1Minimaalne element
max([2, 1, 4, 3])4Maksimaalne element
sum([2, 1, 4, 3])10Elementide summa
sorted([2, 1, 4, 3])[1, 2, 3, 4]Tagastab järjestatud järjendi
3 in [2, 1, 4, 3]TrueKas on selline element?
[2, 1] + [3, 1][2, 1, 3, 1]Järjendite liitmine
[2, 1, 4, 1].count(1)2Elemendi esinemiste arv
[1, 2, 3] == [2, 1, 3]FalseJärjekord on oluline

Katsetage neid julgesti!

Kontrollülesande 5.1 lahendamiseks pole tegelikult kogu seda arsenali vaja. Edasipidi aga võivad erinevad võimalused kasuks tulla küll.

Tabelis on järjendite liitmise tehe, mille abil saame järjendile ka vaid ühe elemendi lisada. Ühe elemendi lisamiseks saab samuti kasutada funktsiooni append. Järgmises näites ongi kummalegi järjendile üks element lisatud.

5.2. For-tsükkel. Funktsioon range

5.2.1. Üksik element teiste seas

Jätkame järjendi teemaga vaadeldes nüüd järjendi ühte konkreetset elementi. Võtame näiteks järjendi a = [12, 23, 34, 45, 56] elemendi, mille indeks on 3. Näeme, et a[3] (või teisiti a[-2]) väärtus on 45. Tegelikult võime a[3] (ja muidugi ka teisi elemente) küllaltki iseseisvatena käsitleda. Näiteks saame seda kasutada avaldistes või anda sellele uue väärtuse.

Nagu näeme, siis on indeksit võimalik arvutades leida. Oluline on vaid, et indeks oleks lubatud vahemikus.

Järjendi idee on siiski kõiki (või vähemalt mingeid) elemente koos käsitleda. Proovime järjendi elemendid järjestikustel ridadel ekraanile saada. Tegemist on selgelt tsüklilise tegevusega, mida saamegi while-tsüklina realiseerida.

Kuna viimase elemendi indeks on ühe võrra väiksem kui järjendi pikkus, siis tõesti selline tsükli tingimus on sobiv. Väljastamise asemel võime ka näiteks kõik need elemendid, mille väärtus on suurem kui 30, nullida.

5.2.2. FOR-TSÜKKEL

Kuna väga sageli on vaja järjendiga just elementhaaval midagi ette võtta, on kasutusele võetud eriline tsükkel. For-tsükkel võtabki järjest igal sammul fookusesse järjendi ühe elemendi.

Elementide väljastamise saame realiseerida nüüd lühemalt.

Muutuja el saab igal tsükli sammul väärtuseks järjendi a järgmise elemendi. Laias laastus on for-tsükkel while-tsükliga sarnane. Esimesel real on päis, mis määrab, millal tsükkel lõpetatakse. Järgneb taandreaga määratud keha (ehk sisu), mida igal sammul täidetakse. Tsüklit korratakse niipalju kordi, kui järjendis on elemente.

Muutuja el kaudu ei saa muuta järjendi elementide väärtusi. Kui püüda teha ülaltoodud teisele while-tsüklile analoogi, siis nii jääb a muutmata.

Mitmetes programmeerimiskeeltes on for-tsükkel teistsugune ja Pythoni for-tsüklile sarnast nimetatakse hoopis for-each-tsükliks.

5.2.3. RANGE

Üsna sageli on vaja selliseid tsükleid, kus tsükli muutuja väärtus teatud reeglite järgi muutub. Meil endalgi oli vaja, et näiteks i omandaks järjest väärtusi 0, 1, 2, 3 jne. Siin tuleb appi funktsioon range, mis genereerib järjendit meenutava väärtuse. Näiteks range(4) annab vahemiku, milles on 0, 1, 2 ja 3. Vajadusel võime ka vastava järjendi saada list(range(4)), aga for-tsükli jaoks seda vaja pole.

Muutuja i saab järjest väärtused 0, 1, 2 ja 3.

Kui argumendiks on mittepositiivne arv, siis ühtegi arvu vahemikus pole.

Vahel meil tegelikult tsükli muutuja väärtust teada pole vajagi, huvitab vaid korduste arv. Paneme näiteks kilpkonna jälle ruutu joonistama

Kuigi muutuja i väärtust vaja ei olnud, pidi see muutuja ikka kirjas olema.

Funktsiooni range saab kasutada ka 2 või 3 argumendiga. Kui on kaks argumenti, siis esimene näitab, millisest arvust alustatakse ja teine, millise arvu juures lõpetatakse (seda ennast mitte kaasates).

Kui teine argument ei ole esimesest suurem, siis ühtegi arvu vahemikus pole.

Kui on kolmaski argument, siis see näitab sammu, mis võib olla ka negatiivne. Nii annab range(0, 13, 2) arvud 0, 2, 4, 6, 8, 10, 12 ja range(4, -5, -3) arvud 4, 1, -2.

Muidugi saab ka erinevates kohtades muutujaid kasutada. Näiteks teeme programmi, mis küsib kasutajalt kaks täisarvu. Seejärel kirjutab ekraanile alates esimesest arvust üle ühe kõik täisarvud kuni teise arvuni (seda mitte kaasates). Ühtlasi leiab ka kõigi väljastatud arvude korrutise.

Näiteks, kui sisestatakse 4 ja 12, siis ekraanile väljastatakse: 4 6 8 10 Korrutis on 1920

Üks võimalik lahendus on selline. Korrutise puhul ei sobi algväärtuseks 0, sest korrutamine seda ei muudaks,

Kontrollülesande 5.2 lahendamisel võib sellest näitest kasu olla.

5.3. Andmed failist

For-tsüklit saame kasutada ka failist andmete lugemiseks. Selline võimalus annab programmidele uue mõõtme – enam me ei pea andmeid programmi sisse kirjutama või kasutajalt sisestamist küsima. Failis võivad andmed olla erineva struktuuriga, näiteks krüpteeritult. Meie piirdume, vähemalt esialgu, selliste failidega, mis on ka inimesele loetavad ja arusaadavad. Räägime lihtsatest tekstifailidest, mis koosnevad ridadest. Failide sisselugemiseks saab kasutada järgmist programmi.

Andmed loetakse failist andmed.txt, mis on programmiga samas kaustas. Faili avamisel oleks võinud kasutada ka ühe argumendiga varianti open("andmed.txt"), aga kuna meil võib tulla tegemist täpitähtedega, täpsustame kodeeringut.

Failist saame read for-tsükliga järjest kätte. Muutujas fail pole siiski järjend vaid mõnevõrra keerukam struktuur, millega aga for-tsükkel kenasti hakkama saab. Tsükli kehas saame konkreetse reaga midagi peale hakata, antud juhul see lihtsalt väljastati ekraanile. Tegelikult aga saab olenevalt rea tähendusest väga huvitavaid ja kasulikke asju teha.

Olgu meil näiteks fail jooks.txt, kus on kirjas, mitu kilomeetrit tervisesportlane erinevatel kordadel jooksis. Teeme programmi, mis kõik need arvud kokku liidab.

Muidugi võib tsükli kehas ka rohkem ridu olla. Näiteks liidame kokku ainult need jooksud, mil joosti üle 10 kilomeetri.

Kui tahame andmetega midagi edasi teha, siis võib olla mõistlik need järjendisse panna.

Enne tsüklit on tehtud tühi järjend: jooksud = []. Tsükli igal sammul järjend pikeneb: jooksud.append(float(rida)) või jooksud += [float(rida)].

Pärast tsüklit väljastatakse järjendi element, mille indeks on 4.

Kontrollülesande 5.3 peaks saama lahendatud juba eeltoodud materjali põhjal.

5.3.1. KUIDAS FAILID TEKIVAD?

Eespool olevates näidetes oli fail, kust andmeid võtta, juba olemas. Selline fail võib olla tekkinud väga erineval moel. Seda, kuidas Pythoni programmiga saab andmeid faili kirjutada, vaatame edaspidi. Tekstiredaktoriga faili koostades peab jälgima, et tegemist oleks lihtsa nö plain-tekstiga. Salvestamisel võiks valikute korral eelistada UTF-8 kodeeringut. Muude korral võib vaja minna programmis kodeeringu muutmist.

Meil on võimalik tekstiredaktorina kasutada Thonnyt ennast. Salvestamisel tuleb lihtsalt salvestustüübina text files valida. Vaikimisi lähevad need failid samasse kausta, kus programmidki ja see meile sobib.

Tohutult palju võimalusi pakuvad avalikud andmebaasid, kust saame kõigepealt sobiva tabeli alla laadida ja seda siis oma programmi abil analüüsida. Vastav näide on selle materjali lõpus. Siinkohal lihtsalt mõned lingid: http://www.stat.ee/http://haridussilm.ee/http://ec.europa.eu/eurostat.

5.3.2. PANGAAUTOMAAT RAHVUSVAHELISEKS

Failidest andmete saamisega saame täiendada pangaautomaadi programmi nii, et saaks keelt valida.

Programmi tööks vajalikud failid on est.txteng.txt ja ger.txt.

5.3.3. KILPKONNA TRANSLAATOR

Failis võib olla hoopis programmitekst. Tegelikult ju meie programmide tekstid ongi lihtsalt tekstifailid. Olgu meil näiteks failis kirjas, kuidas kilpkonn peaks liikuma

    edasi 40
    paremale 90
    edasi 50
    tagasi 30
    vasakule 90
    edasi 30

Kirjutame sellise programmi, mis selle teksti kilpkonnale arusaadavaks tõlgib.

Näeme, et kilpkonn saigi niimoodi eestikeelsetest käskudest aru. Programm oskab tõlkida (ingl translating)! Tegelikult nimetataksegi selliseid programme, mis programmiteksti arvutile arusaadavaks teevad translaatoriteks.

5.3.4. AVALIKUST ANDMEBAASIST

Eespool juba mainisime avalikke andmebaase. Näiteks statistikaameti kodulehel https://www.stat.ee/ on väga palju huvitavat informatsiooni. Siin saab ise andmeid valida ja sobivas formaadis salvestada. Kuigi pakutakse ka tekstifaili, on meile siin sobivam tabeldieraldusega pealkirjata tekst (.csv) või semikooloneraldusega pealkirjata tekst (.csv). Mõlemal juhul tekib csv-fail. Formaadinimi csv on lühend sõnadest comma-separated values (komaga eraldatud väärtused). Kuigi vahel kasutataksegi väärtuste eraldajana tõesti koma, siis paljudel juhtudel on eraldajaks hoopis tabeldusmärk (Pythonis “\t”) või semikoolon.

Näiteks võib rida failis RV031sm.csv olla selline (loomulik iive 1923. aastal). "1923";3636

Nüüd on vaja see rida semikooloni kohalt osadeks jaotada ja osad täisarvudena esitada. Osadeks saab jaotada funktsiooni split abil, mis tekitab antud juhul kahe elemendiga sõnejärjendi. Üks element on sõne '"1923"' ja teine '3636'. Tegelikult tahame mõlemal juhul saada täisarve. Kuna esimesel juhul on sõnes endas jutumärgid, siis tuleb need eemaldada näiteks funktsiooni strip abil.

5.4. Silmaring: krüpteerimine

Autor: Kristjan Krips

5.4.1. SISSEJUHATUS

Selle nädala silmaringi materjalis teeme lühikokkuvõtte sellest, mis on krüpteerimine ja miks seda vaja läheb. Ajaloo osas mainisime masinat nimega Enigma, mida kasutati Teise maailmasõja ajal militaarsõnumite kaitsmiseks pealtkuulajate eest. Enigma oli masin, mis võimaldas andmeid krüpteerida ning seega neid kaitsta kolmandate osapoolte eest (näiteks sakslaste andmete kaitsmist inglaste eest). Enigma muutis masinasse sisestatud andmeid nii, et masinast väljuvad andmed olid kolmandale osapoolele loetamatud.

Enigma. Allikas

5.4.2. KODEERIMINE

On oluline tähele panna, et Enigma puhul polnud tegu andmete lihtsa kodeerimisega, sest kodeeritud andmeid on kerge taastada. Lihtne kodeerimise näide on morsekood, mis muudab kindla eeskirja alusel andmeid ning võimaldab neid selle sama eeskirja alusel taastada.

Krüpteerimine erineb kodeerimisest selle poolest, et andmete töötlemisel kasutatakse võtit, mistõttu kolmas osapool ei saa ilma võtit omamata krüpteeritud andmetest esialgset taastada.

Morse on näide kodeerimisest. Allikas

5.4.3. KRÜPTEERIMINE

Tänapäeval on krüpteerimine põhiline viis digitaalsete andmete kaitsmiseks. Krüpteerimise abil kaitstakse telefonikõnesid pealtkuulamise eest ning meditsiiniandmeid ja ärisaladusi lekkimise eest. Muuhulgas kasutatakse krüpteerimist tasuliste telekanalite edastamisel, wifi võrgu kaitsmisel, HTTPS protokolli kasutavate veebilehtedega suhtlemisel, digiallkirjastamisel ja e-hääletamisel. Krüpteeritud ühenduse kasutamine on üks oluline meetod turvalise internetipanga teenuse pakkumisel. Kuna krüpteerimine mõjutab meid iga päev, siis võib tekkida küsimus, kuidas ikkagi krüpteerimine toimib ning kas ründajal on võimalik krüpteeritud sõnumeid lahti murda.

5.4.4. SÜMMEETRILINE KRÜPTEERIMINE

Kõige lihtsam on krüpteerimist ette kujutada nii, et on olemas krüpteerimisalgoritm (eeskiri), mis saab sisendiks andmed ja krüpteerimisvõtme ning annab väljundiks krüpteeritud andmed. Nende krüpteeritud andmete taastamiseks on vaja kasutada dekrüpteerimise (lahtikrüpteerimise) võtit ning ilma vastava võtmeta pole võimalik andmeid esialgsel kujul taastada. Juhul kui krüpteerimisvõti ja dekrüpteerimisvõti on samad, siis on tegu sümmeetrilise krüpteerimisalgoritmiga. Niisuguseid algoritme kasutatakse suurte andmehulkade krüpteerimiseks, hea näide on kõvakettal või mälupulgal olevate andmete kaitsmine.

Krüpteerimine ja dekrüpteerimine

Nüüd võib tekkida küsimus, et mis on see võti, mida krüpteerimisel ja dekrüpteerimisel kasutatakse. Vastav võti on mõnes mõttes sarnane tavalise lukuvõtmega — võtit tuleb valvata, et sellest koopiat ei tehtaks, ja võtit tuleb kaitsta kadumise eest, et võõrad võtit kasutada ei saaks. Lisaks sellele tuleb võtit enda jaoks säilitada, et tagada juurdepääs võtmega suletud hoiukohtadele või ruumidele. Oluline on märkida, et ka krüpteeritud andmetele on võimalik juurde pääseda ainult vastavat võtit kasutades. Võti on kahendsüsteemis arv ehk siis ühtedest ja nullidest koosnev jada. Tänapäevaste sümmeetriliste krüpteerimissüsteemide korral on võtmed enamasti 128-bitised või 256-bitised ehk siis ühtede ja nullide jadad pikkusega 128 või 256 märki. On väga oluline, et krüpteerimisel kasutatav võti oleks juhuslikult genereeritud, sest krüpteerimise tugevus sõltub nii krüpteerimisalgoritmi kui ka võtme tugevusest.

Samas toob juhuslike bitijadade kasutamise nõue endaga kaasa kaks probleemi:

  1. Esimene probleem seisneb selles, et juhuslike võtmete genereerimine ei ole lihtne, sest arvutid ei suuda päris juhuslikke arve genereerida.
  2. Teine probleem on seotud sellega, et inimesed ei ole võimelised meelde jätma pikki nende jaoks seosetuid bitijadasid.

Seetõttu krüpteeritakse võti enamasti parooliga, mida on inimesel lihtsam meelde jätta, ning krüpteeritud võti salvestatakse kas eraldi failina, lisatakse krüpteeritud faili päisesse või hoitakse eraldiseisval kiibil.

Andmete krüpteerimiseks on vaja valida sobiv krüptosüsteem. Krüptosüsteem koosneb:

  • võtme genereerimise algoritmist,
  • andmete kaitsmiseks mõeldud krüpteerimisalgoritmist ja
  • andmete taastamiseks mõeldud dekrüpteerimisalgoritmist.

Krüptosüsteemi valikul tuleks lähtuda selle turvalisusest. Tänapäeval on sümmeetrilise krüpteerimise korral standardlahenduseks AES-i (Advanced Encryption Standard) kasutamine. AES krüpteerib andmeid 128-bitiste plokkide kaupa, täpsemat infot AES-i toimimise kohta leiate vastavalt Wikipedia lehelt: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard.

AES-i pakutavat krüpteeringut peetakse murdmatuks. See tähendab seda, et isegi superarvutid ei suuda AES-i abil krüpteeritud andmeid lahti murda, sest leitud pole ühtegi olulist krüptograafilist viga ning kõikide erinevate võtmete proovimiseks kuluks miljoneid aastaid. See kehtib ainult vastava süsteemi korrektsel kasutamisel, mis tähendab seda, et võti on genereeritud juhuslikult ning see ei leki. Juhul kui AES võtme kaitsmiseks kasutatav parool on lühike, näiteks kaheksa sümboli pikkune, siis on võimalik kõikvõimalike lühikeste paroolide proovimise teel vastav parool üsna kiiresti üles leida ning seega andmed dekrüpteerida. Samuti on vaikimisi eelduseks, et krüpteerimistarkvara on kirjutatud spetsialistide poolt, et see ei lekitaks infot krüpteeritavate andmete või võtmete kohta. Krüptoalgoritmide programmeerimine ei ole lihtne, sest info võib lekkida väga erinevatest kohtadest, näiteks protsessori energiatarbimise kaudu.

5.4.5. SÜMMEETRILISE KRÜPTEERIMISEGA SEOTUD PROBLEEMID

Sümmeetriline krüpteerimine võimaldab andmeid kaitsta, kuid probleemiks osutub krüpteeritud andmete jagamine teiste osapooltega. Kuna sümmeetrilise krüpteerimise korral kasutatakse krüpteerimiseks ja dekrüpteerimiseks sama võtit, siis oleks krüpteeritud andmete jagamisel vaja edastada ka võti.

Nüüd tekib küsimus, et kui turvaline on võtme jagamine ja edastamine. On oluline tähele panna, et kui võtit ja krüpteeritud andmeid edastatakse koos, siis saab pealtkuulaja juurdepääsu krüpteeritud andmetele ning seega poleks andmed kaitstud. Seega oleks võtme edastamiseks vaja turvatud sidekanalit. Samas, kui suhtluspartnerite vahel on juba olemas turvatud sidekanal, siis ei olegi enam vajadust andmeid eraldi krüpteerida.

Mida teha olukorras, kus suhtluspartnerite vahel ei ole turvatud sidekanalit ning nad peavad edastama konfidentsiaalseid andmeid? Võimalik on kasutada kahte erinevat ebaturvalist sidekanalit (näiteks edastatakse parool käsitsi ümbrikus), lootuses, et pealtkuulaja ei saa mõlemat kanalit pealt kuulata ning seetõttu ei saa juurdepääsu kas krüpteeritud andmetele või siis võtmele. Samas ei paku niisugune süsteem suhtluspartneritele kindlust, et nende saadetud konfidentsiaalsed andmed jäävad salajaseks.

Isegi kui õnnestub leida turvaline viis võtme edastamiseks, siis tekib teine probleem. Nimelt on vaja iga sõnumi jaoks genereerida uus võti, sest juhul kui suhtluspartner lekitab võtme (näiteks portaal ei turva paroole piisavalt hästi), siis saaksid kolmandad osapooled järgmisi sõnumeid lugeda. See omakorda tekitab vajaduse turvalise võtmehalduse jaoks.

Neid probleeme saab lahendada avaliku võtme krüptograafia ehk asümmeetrilise krüptograafia abil.

Allikas

5.4.6. ASÜMMEETRILINE KRÜPTEERIMINE

Asümmeetrilise krüpteerimise ehk avaliku võtme krüpteerimise korral kasutatakse kahte võtit — avalikku ja salajast võtit. Need võtmed genereeritakse korraga ning nad on omavahel seotud nii, et avalik võti ei lekita informatsiooni salajase võtme kohta. Võtmete genereerimine peab olema juhuslik.

Nii nagu nimigi ütleb, on üks võti avalik ning seda võib kõigiga jagada. Samas tuleb salajast võtit kaitsta lekkimise eest. Asümmeetrilise krüpteerimise korral on kõigil osapooltel enda võtmepaarid. Näiteks on kõigil Eesti ID-kaardi omanikel kiibis võtmepaar. Samuti on kõigil HTTPS pakkuvatel veebilehtedel oma võtmepaar.

Avalikku võtit kasutatakse andmete krüpteerimiseks ning vastavat salajast võtit kasutatakse andmete dekrüpteerimiseks. Seega võimaldab asümmeetrilise krüptograafia kasutamine lihtsamat võtmevahetust, sest avalikku võtit saab edastada ebaturvalise sidekanali abil. Kui on vaja suhtluspartnerile saata konfidentsiaalseid andmeid, siis kõigepealt on vaja küsida suhtluspartneri avalikku võtit ning siis saab seda kasutada, et konfidentsiaalseid andmeid krüpteerida. Kuna krüpteerimiseks kasutati suhtluspartneri avalikku võtit, siis saab vastavalt krüpteeritud andmeid dekrüpteerida ainult see sama suhtluspartner, sest ainult temal on juurdepääs sobivale salajasele võtmele.

Selgituseks võtame näite, kus Kristjan tahab Taunole saata krüpteeritult salajast faili. Selleks peab:

  1. Tauno jagama Kristjaniga enda avalikku võtit. Näiteks on ID-kaardi kiibis võtmepaar (avalik ja privaatne võti) ja Tauno jagab Kristjaniga ID-kaardi avalikku võtit. See pole probleem, sest ID-kaardi avalikud võtmed ongi vabalt jagatavad.
  2. Seejärel Kristjan krüpteerib faili kasutades Tauno ID-kaardi avalikku võtit ning saadab krüpteeritud faili Taunole.
  3. Nüüd ei jää Taunol muud üle, kui kasutada ID-kaardi kiibil olevat privaatset võtit ja saabki esialgsele failile kenasti ligi.

Tegelikult küll kasutatakse suuremate andmete krüpteerimiseks alati sümmeetrilist krüptograafiat ning seega selles olukorras hübriidsüsteemi, kus genereeritakse sümmeetriline võti, sellega krüpteeritakse fail ja võti ise krüpteeritakse siis vastava avaliku võtmega.

Juhul kui aga võtmeid kasutatakse vastupidi, siis on tegemist digiallkirjastamisega. Sellisel juhul krüpteeritakse andmed salajase võtmega ning seda saab teha ainult salajase võtme omanik. Digiallkirja kontrollimiseks kasutatakse vastavat avalikku võtit ning seda saavad teha kõik, kellel on juurdepääs vastavale avalikule võtmele.

Krüpteerimine ja dekrüpteerimine salajase ja avaliku võtmega