Használható segédanyagok: Haskell könyvtárainak dokumentációja, (lokális!) Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármilyen kérdés, észrevétel felmerül, azt a felügyelőknek kell jelezni, NEM a diáktársaknak!
Tekintve, hogy a tesztesetek, bár odafigyelés mellett íródnak, nem fedik le minden esetben a függvény teljes működését, határozattan javasolt még külön próbálgatni a megoldásokat beadás előtt, vagy megkérdezni a felügyelőket!
Részpontszámokat csak az elégséges szint elérése után lehet kapni!
Ebben a feladatban egy jelszavakat ábrázoló típust és annak néhány műveletét kell megvalósítanunk. Az implementáció során alkalmazott egyes ötleteket a feladatokon keresztül mutatjuk be.
A jelszavakat általában szöveges formában kapjuk meg. Biztonsági okokból azonban nem közvetlenül ezt az alakját használjuk fel az ellenőrzés során, hanem ebből képezünk egy egész számot egy megfelelő függvény segítségével.
Ehhez először bevezetjük a Hash
szinonímát, amely ilyen egész számokat jelöl.
A leképezéshez használt függvényünk képlete legyen a következő:
Tehát vegyük a karakterlánc egyes karaktereinek kódját (a Data.Char.ord
függvénnyel), emeljük a 2-t ennek megfelelő hatványokra, majd ezt sorozzuk össze poziciónak megfelelő pozitív egész számmal, végül adjuk össze az egyes karakterekhez az előbbiek szerint kiszámolt részeredményeket.
Óvatosnak kell lennünk viszont akkor, amikor több, ugyanazzal a módszerrel leképzett jelszót tárolunk egyazon állományban. Ha ugyanis ezt eltulajdonítják, akkor ugyanazt a módszert próbálgatva könnyedén vissza tudják fejteni a jelszavainkat. Ezért találták ki, hogy a kódolási eljárás során valamilyen további függvénnyel normalizálják (általában erősítik) a felhasználótól kapott jelszót.
Ehhez most mi is bevezetünk további két szinonímát: a Salt
típust, amely a jelszóhoz hozzáadandó toldalékot ábrázolja, valamint a KDF
(mint key derivation function) típust, amely leírja, hogy milyen módon transzformáljuk tovább a jelszót.
Feladatunk most egy egyszerű kulcsleképezés elkészítése. Ebben az esetben a kulcsot úgy képezzük a kapott karakterláncból, hogy összefűzzük a toldalékkal, majd a saját megfordítottjával.
Készítsünk egy másik kulcsleképző függvényt: ebben az esetben fogjuk a karakterláncot és utánamásoljuk a toldalékot addig, amíg a megadott hosszt nem el értük. (Természetesen, ha a jelszó eleve hosszabb ennél, akkor ehelyett abból fogunk levágni.) Ha a toldalék üres, akkor magát a karakterláncot ismételgetjük a kívánt hossz eléréséig.
Ezután már meg tudjuk adni a jelszavakat ábrázoló típust.
Ebben tehát látható, hogy egy jelszót a belőle képzett egész számmal és a hozzá tartozó toldalékkal írunk le.
Az előbbieknek megfelelően tehát egy jelszót egy kulcsleképezés, egy toldalék és egy karakterlánc birtokában tudunk előállítani. Először a toldalék felhasználásával a karakterláncból képezzünk kulcsot, majd számítsuk ki a neki megfelelő egész számot!
A jelszavak ellenőrzése ehhez nagyon hasonló. Megkapjuk a jelszó (fentiek szerint) kódolt alakját, a rendelkezésre álló kulcsleképező függvényeket és az ellenőrizendő jelszót. A kulcsleképzéseket próbálgatva nézzük meg, hogy valamelyikkel kapunk-e olyan jelszót, amely egyező egész számot generál!
Láthatjuk, hogy valójában jelszavanként változhat (a toldalékkal együtt) a leképezés módja is. Viszont ezt nem tároltuk el a jelszóval, ezért kell végigpróbálni. Célunk ezzel is nehezíteni a visszafejtést.
A következő lépésben szeretnénk a jelszavainkat szöveges állományokban tárolhatóvá tenni. Ehhez először tudnunk kellene ezeket karakterláncokká alakítani.
Ehhez bevezetjük az Alphabet
típust, amely a kódoláshoz használt ábécét fogja ábrázolni (mint karakterek sorozata).
Egy ilyen minta ábécé lehet például az alábbi:
A jelszavak szöveges ábrázolásának alapját egy olyan függvény képezi, amely a jelszóhoz kiszámolt Hash
értéket tudja szövegre alakítani a megadott ábécé szerint. Itt lényegében egy olyan átváltásra kell gondolnunk, ahol a számrendszert az ábécé hossza adja meg, és ennek számjegyei az ábécében szereplő szimbólumok.
Megjegyzés: A könnyebb implementáció érdekében az így kiszámolt számjegyek kövessék egymást fordított sorrendben!
A jelszavak teljes szöveges alakjához még az hiányzik, hogy a fenti módszerrel előállított karaktersorozathoz hozzá tudjuk tenni a kódolás során alkalmazott toldalékot.
Ehhez bevezetjük az elválasztójelet ábrázoló Separator
típust:
amelynek lehet például a dollárjel:
A jelszavakból szöveget tehát úgy tudunk készíteni, ha az adott ábécé szerint átalakítjuk a jelszót ábrázoló egész számot, majd ehhez az elválasztójellel hozzáfűzzük a kulcsképzésnél alkalmazott toldalékot.
A szöveges változat létrehozásán kívül még fontos, hogy be is tudjuk olvasni szövegből jelszavakat, adott ábécé szerinti kódolással. Ebben a függvényben a jelszót ábrázoló egész szám kódolt alakját kell tudnunk visszaolvasni. Arra viszont figyeljük, hogy nem minden esetben található meg a visszakódolandó szöveg összes karaktere az ábécénkben. Ezért ez utóbbi esetben ne adjon a függvény vissza eredményt!
Végül készítsük el azt a függvényt, amellyel a teljes jelszót be tudjuk olvasni! Ehhez először a megadott elválasztójel mentén szét kell bontanunk a szöveget. Amennyiben ez nem lehetséges, akkor a függvény ne adjon vissza eredményt! Ha sikerült, akkor az előbbiek szerint kódoljuk vissza a Hash
értéket és a toldalékkal együtt képezzünk belőle jelszót. Ha a visszakódolás nem sikerült (nem ad eredményt), akkor ez a függvény se adjon eredményt!