Kirjautuminen

Haku

Tehtävät

Koodit: Assembly: Henkilötunnus

Kirjoittaja: Antti Laaksonen

Kirjoitettu: 16.01.2008 – 16.01.2008

Tagit: ohjelmointitavat, koodi näytille, vinkki, DOS

Henkilötunnuksen tarkistus on ohjelmointiväen kansanhuvia, vaikka harva ohjelma pääsee loppujen lopuksi tositoimiin tuntemattomien henkilötunnusten tarkistuksessa.

Tässä on DOS-ympäristössä toimiva assembly-ohjelma, joka lukee käyttäjältä henkilötunnuksen alkuosan ja lisää sen perään oikean tarkistusmerkin. Ohjelman voi kääntää nasm-kääntäjällä seuraavalla komennolla:

nasm -f bin hetu.asm -o hetu.com

Henkilötunnuksen tarkistusmerkki lasketaan muodostamalla henkilötunnuksen alkuosasta yhdeksännumeroinen luku, jakamalla tämä luku 31:llä ja katsomalla taulukosta jakojäännöstä vastaava tarkistusmerkki. Tarkka selostus laskutavasta on esim. Väestörekisterikeskuksen sivulla:

http://www.vaestorekisterikeskus.fi/vrk/home.nsf/pages/32C708B9CA6C5824C2256CB70038D048

Assembly-ohjelmaan kuuluu kaksi aliohjelmaa, jotka lukevat käyttäjältä yhden numeron ja välimerkin. Kun numerot luetaan yksi kerrallaan, luvun suuruus saadaan selville kertomalla aiemmin luettu osa 10:llä ja lisäämällä siihen uusi numero. Kuitenkin ainoa kiinnostava tieto on luvun jakojäännös 31:llä, minkä vuoksi pidetään kirjaa vain muodosteilla olevan luvun jakojäännöksestä 31:llä.

Tässä astuu kuvaan ohjelmointitemppu, jolla vältetään hankalat MUL- ja DIV-komennot. Aputaulukkoon on laskettu etukäteen, miten luvun jakojäännös 31:llä muuttuu, kun luku kerrotaan 10:llä. Tällä tavalla 10:llä kertomiseksi riittää noutaa taulukosta uusi jakojäännös. Uusi numero lisätään tavalliseen tapaan lukuun, mutta jos näin saatu luku on 31 tai suurempi, luvusta vähennetään 31.

Esimerkiksi luvun muodostuksessa saattaa esiintyä tilanne, jossa on luettu numerot 241 ja nyt vuorossa on numero 2. Lopputulos on tietysti 2412, jonka jakojäännös 31:llä on 25. Tässä ohjelmassa kuitenkin muistissa on 241:n asemesta pelkkä saman luvun jakojäännös 31:llä, joka on 24. Aputaulukkoon on kirjattu, että 10:llä kertominen tuottaa uudeksi jakojäännökseksi 23. Tähän pitää enää lisätä luku 2, jolloin jakojäännös on 25 ja tulos täsmää.

Tarvittavan aputaulukon voi laatia esim. tällä QBasic-ohjelmalla:

FOR i% = 0 TO 30
   PRINT i%, (i% * 10) MOD 31
NEXT

Saattaa herätä kysymys, mitä järkeä moisen aputaulukon käytössä on. Tässä tapauksessa koodi hieman lyhentyy ja vältytään kertolaskuilta ja jakolaskuilta. Kuitenkin tarvitaan ylimääräinen taulukko muistia kuluttamaan. 10:llä kertominen ja 31:llä jakaminen eivät ole kaikesta huolimatta kovin monimutkaisia toimintoja, joten kenties tällä kertaa taulukon laatiminen on hieman liioittelua. Mutta jos pitäisi suorittaa vastaavassa tilanteessa jokin monimutkainen lasku (edelleen jakojäännöksillä), taulukosta voisi olla paljon hyötyä.

Ohjelma käyttää DOSin keskeytyksiä merkin lukuun, merkin tulostukseen ja ohjelman sulkemiseen. Keskeytysten toimintaan voi perehtyä esim. seuraavassa osoitteessa:

http://heim.ifi.uio.no/~stanisls/helppc/idx_interrupt.html

org 100h

        xor bx, bx              ; nollataan laskuri
        call numero             ; luetaan 6 numeroa
        call numero
        call numero
        call numero
        call numero
        call numero
        call vali               ; luetaan välimerkki
        call numero             ; luetaan 3 numeroa
        call numero
        call numero

        mov dl, [merkit+bx]     ; haetaan tarkistusmerkki
        mov ah, 02h             ; näytetään tarkistusmerkki
        int 21h

        mov ax, 4c00h           ; poistutaan ohjelmasta
        int 21h

numero: mov bl, [kertot+bx]     ; kerrotaan laskuri 10:llä
        mov ah, 01h             ; luetaan numeromerkki
        int 21h
        sub al, '0'             ; puretaan ASCII-koodi
        add bl, al              ; lisätään numero laskuriin
        cmp bl, 31              ; vähennetään tarvittaessa 31
        jl valmis
        sub bl, 31
valmis: ret

vali:   mov ah, 01h             ; luetaan välimerkki
        int 21h
        ret

; henkilötunnuksen tarkistusmerkit
merkit  db "0123456789ABCDEFHJKLMNPRSTUVWXY"

; 10:llä kertomisen vaikutus laskuriin
kertot  db 0,10,20,30,9,19,29,8,18,28,7,17,27,6,16,26,
        db 5,15,25,4,14,24,3,13,23,2,12,22,1,11,21

Kommentit

Jakke1 [16.01.2008 16:27:03]

#

Oho. Mitä muuta Asm ohjelmointiin tarvitsee kuin OllyDbg:N?

Antti Laaksonen [16.01.2008 20:40:06]

#

Käännetty ohjelma (133 tavua) on osoitteessa:

http://koti.mbnet.fi/pllk/muut/hetu.com (päivitetty 17.1.)

Jakke1: Sopiva kääntäjä (esim. nasm) ja tekstieditori riittävät.

Päärynämies [16.01.2008 21:14:16]

#

Ihan kiva "lisä" vinkkiin tuo jakojäännösten taulukoiminen, jolloin noiden, ei ehkä hankalien, mutta aikaavievien kerto- ja jakolaskujen tarve poistuu.

Tietysti dos-vinkit eivät enää ehkä niin ajankohtaisia ole, mutta onhan tässäkin monia ainakin aloittelijoille kivoja asioita. Tietysti nuo peräkkäiset saman aliohjelman kutsut olisi voinu laittaa looppiin, jolloin koodi olisi ehkä esteettisempi.

FooBat [17.01.2008 21:27:24]

#

Toimiikos toi nyt varmasti oikein? Itse sain tarkistusmerkiksi '8' vaikka oikea olisi ollut 'T'.

Antti Laaksonen [17.01.2008 21:56:24]

#

Yksi virhe ainakin paljastui jakojäännöslaskusta (komennon jl tilalla oli jng). Toimiiko nyt oikein?

FooBat [17.01.2008 23:43:45]

#

Nyt näyttää toimivan ainakin mun hetulla.

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta