Page 1 of 1

Henkilötunnusgeneraattori?

Posted: Thu Mar 17, 2011 11:24 pm
by TukeKoodi
Juu oon omaks harjoitukseks tekemäs hetugeneraattorii selvittämään montako eri mahdollisuutta on jos tietää henkilön syntymäajan ja sukupuolen.
Wikipedia kirjoitti:
Suomalaisen henkilötunnuksen muodosta on säädetty väestötietoasetuksessa 128/2010.[1] Se koostuu 11:stä merkistä ja on muotoa xxxxxxyzzzq, jossa
xxxxxx on henkilön syntymäaika muodossa ppkkvv, esimerkiksi 010180
y on sen vuosisadan tunnus, jolloin henkilö on syntynyt.
1800-luku: +
1900-luku: −
2000-luku: A
zzz on yksilönumero, jolla samana päivänä syntyneet yksilöidään. Luku on naisilla parillinen ja miehillä pariton. Yksilönumero on välillä 002–899. Välin 900–999 numeroita käytetään tilapäisissä henkilötunnuksissa, esimerkiksi sairaaloissa, kun virallista henkilötunnusta ei tiedetä tai sitä ei ole vielä syntyneelle lapselle annettu. Tilapäisiä tunnuksia ei kirjata väestötietojärjestelmään. Yksilönumerot pyritään pitämään yksilöllisinä siten, että 2000-luvulla syntyneiden numerosarja jatkuu siitä, mihin vastaava 1900-luvun sarja päättyi.
q on tarkistusmerkki. Tarkistusmerkki lasketaan jakamalla syntymäajan ja yksilönumeron muodostama 9-numeroinen luku 31:llä [2]. Jakojäännös, joka on tällöin kokonaisluku väliltä 0–30, muunnetaan tarkistusmerkiksi alla olevan taulukon mukaisesti [2]. Vuosisadan tunnus ei siis vaikuta tarkistusmerkkiin.
http://fi.wikipedia.org/wiki/Henkil%C3%B6tunnus


Eli syntymäaika esim 010199 ja sukupuoli mies. Ohjelman pitäisi ottaa luvusta 003 lähtien lukuun 899 jokainen pariton luku, kirjoittaa ne tiedostoon muotoon:

Code: Select all

WriteLine hetu_file, 021299+"-"+(parittomat 003-899)+tunnus_kirjain[1]
[1] = 021299 yhdistettynä parittomat 003-899, esim 021299123 / 31 jakojäännös ja sen mukaan kirjain linkin takana olevasta taulukosta esim.

Code: Select all

Select tunnus
Case 16
tunnus_kirjain = "H"
...
End Select
Eli mitä olen saanut tehtyä: (ongelmana lukujen "yhdistäminen" ja parillisten poistaminen (koska sukupuoli mies))

Code: Select all

f=OpenToWrite("C:\asd.txt")

tunnus_kirjain$ = ""

Repeat

    tunnus = 010199//Yhdistettynä(?) i Mod 31

    Select tunnus
    
        Case 0
        tunnus_kirjain = "0"
        
        Case 1
        tunnus_kirjain = "1"
        
        Case 2
        tunnus_kirjain = "2"
        //Yhdeksään asti samaa...
        Case 10
        tunnus_kirjain = "A"
        
        Case 11
        tunnus_kirjain = "B"
        //Jne. taulukon mukaisesti...
        
    EndSelect

    For i = 002 To 899
        WriteLine f, "010199"+"-"+i+""+tunnus_kirjain
    Next i

    If i > 898 Then End

Forever
EDIT:

En tietenkään omaa syntymäaikaani laittanut :D


Re: Henkilötunnusgeneraattori?

Posted: Thu Mar 17, 2011 11:43 pm
by valscion
Voit tarkistaa, onko luku parillinen käyttämällä myös Mod-operaattoria. Näin:

Code: Select all

If (1 Mod 2) Then Print "1 on pariton!" Else Print "1 on parillinen!" 
If (14 Mod 2) Then Print "14 on pariton!" Else Print "14 on parillinen!"
If (5721633 Mod 2) Then Print "5721633 on pariton!" Else Print "5721633 on parillinen!"
WaitKey 

Re: Henkilötunnusgeneraattori?

Posted: Thu Mar 17, 2011 11:47 pm
by TukeKoodi
Entäs tää lukujen yhdistäminen esim. 1 ja 2 = 12

Re: Henkilötunnusgeneraattori?

Posted: Thu Mar 17, 2011 11:49 pm
by valscion
TukeKoodi wrote:Entäs tää lukujen yhdistäminen esim. 1 ja 2 = 12
Tallenna numerot aluksi merkkijonona, jolloin voit lisätä niitä noin yhteen. Eli "1" + "2" = "12". Sitten kun haluat myöhemmin tarkistaa sen jakojäännöksen luvun 31 kanssa, käytät Int-funktiota ja Mod-operaattoria.

Re: Henkilötunnusgeneraattori?

Posted: Thu Mar 17, 2011 11:53 pm
by Latexi95
VesQ wrote:
TukeKoodi wrote:Entäs tää lukujen yhdistäminen esim. 1 ja 2 = 12
Tallenna numerot aluksi merkkijonona, jolloin voit lisätä niitä noin yhteen. Eli "1" + "2" = "12". Sitten kun haluat myöhemmin tarkistaa sen jakojäännöksen luvun 31 kanssa, käytät Int-funktiota ja Mod-operaattoria.
Eli siis:

Code: Select all

Function Plussaa(luku1,luku2)
     return Int(Str(luku1) + Str(luku2))
EndFunction

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 12:10 am
by TukeKoodi
Miks tää ei toimi?

Code: Select all

f=OpenToWrite("C:\asd.txt")

tunnus_kirjain$ = ""

Repeat

    yhdistetty$ = Plussaa (021190, i)

    tunnus = (Int (yhdistetty) Mod 31)
   

    Select tunnus
    
        Case 0
        tunnus_kirjain = "0"
        
        Case 1
        tunnus_kirjain = "1"
        
        Case 2
        tunnus_kirjain = "2"
        //Yhdeksään asti samaa...
        Case 10
        tunnus_kirjain = "A"
        
        Case 11
        tunnus_kirjain = "B"
        
        Case 16
        tunnus_kirjain = "H"
        
        Default
        tunnus_kirjain = "???"
        //Jne. taulukon mukaisesti...
        
    EndSelect

    For i = 002 To 899
    If (i Mod 2) Then
        WriteLine f, "021190"+"-"+i+""+tunnus_kirjain
        EndIf
    Next i

    If i > 898 Then End
    
Forever

Function Plussaa(luku1,luku2)
     Return Int(Str(luku1) + Str(luku2))
EndFunction

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 12:15 am
by esa94
TukeKoodi wrote:Miks tää ei toimi?

Code: Select all

    yhdistetty$ = Plussaa (021190, i)
Koska Plussaa palauttaa kokonaisluvun, ei merkkijonoa.

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 12:20 am
by valscion
TukeKoodi wrote:Miks tää ei toimi?
Sinulla on funktiokutsu "yhdistetty$ = Plussaa (021190, i)" ulkopuolella For...Next silmukasta, jossa sitä i-muuttujan arvoa muutetaan jokaisella kierroksella. Siirrä tuo koodipätkä sen silmukan sisään niin taitaa sillä toimia.

Ja esalle, niin sillä ei ole väliä, koska se lisätään merkkijonoon. Silloin CB muuttaa luvun automaattisesti merkkijonoksi.

Ongelmaksi lähinnä sinulle tulee siinä tapauksessa kun i saa arvoja, jotka ovat alle kolminumeroisia. Koska i on kokonaisluku eikä merkkijono, riisutaan sen alusta turhat nollat pois. Sinun tulee tarkistaa If-lauseilla että pitääkö ennen i:tä lisätä nollia että numero olisi oikein ennen tiedostoon kirjoittamista For-loopissasi.

Code: Select all

For i=1 To 150
    If i<10 Then
        iStr$ = "00" + i
    ElseIf i<100 Then
        iStr$ = "0" + i
    Else
       iStr$ = i
    EndIf
    Print iStr + " - Vertaa tähän: " + i
    Wait 100
Next i

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 12:28 am
by TukeKoodi
VesQ wrote:
TukeKoodi wrote:Miks tää ei toimi?
Sinulla on funktiokutsu "yhdistetty$ = Plussaa (021190, i)" ulkopuolella For...Next silmukasta, jossa sitä i-muuttujan arvoa muutetaan jokaisella kierroksella. Siirrä tuo koodipätkä sen silmukan sisään niin taitaa sillä toimia.
Ei se tolla toimi, valittaa muuttujien merkeistä(?) ($, # jne.)

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 12:43 am
by valscion
TukeKoodi wrote:
VesQ wrote:
TukeKoodi wrote:Miks tää ei toimi?
Sinulla on funktiokutsu "yhdistetty$ = Plussaa (021190, i)" ulkopuolella For...Next silmukasta, jossa sitä i-muuttujan arvoa muutetaan jokaisella kierroksella. Siirrä tuo koodipätkä sen silmukan sisään niin taitaa sillä toimia.
Ei se tolla toimi, valittaa muuttujien merkeistä(?) ($, # jne.)
Sinun pitää muistaa laittaa kaikkiin merkkijonoina käytettäviin muuttujiin $-merkki perään. Sinun tulee myös itse asiassa laittaa lähes kaikki koodi tuon For-loopin sisään, jotta homma toimisi. Ajattele mitkä kaikki muuttujat täytyy päivittää ennen rivin kirjoittamista tiedostoon ja laita sen mukaan tavaraa sen for-loopin sisään niin hyvä tulee.

Muista myös sulkea tiedosto CloseFile komennolla. Jos satut käyttämään Win7:aa tai Vistaa, voi olla että käyttäjäoikeudet ohjelman suorittamiselle eivät riitä tiedoston "asd.txt" luomiseksi C:/ -osion juureen. Laita mielummin poluksi vaikka omat tiedostot -kansio ja sinne sisään se asd.txt tiedosto niin sen luominen onnistuu paljon varmemmin.

P.S.
Myös tuo sinun Repeat...Forever silmukkasi on melko turha. Tarvitset vain For...Next looppia ja kun se on läpikäyty, sulje tiedosto ja sammuta ohjelma (tai oikeastaan se sammuu itsekseen kun koodi loppuu).

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 8:27 am
by TukeKoodi
Kiitos, laitoin kaikki muuttujat paitsi tunnus_kirjain For...Next loopin sisään ja nyt toimii!

Re: Henkilötunnusgeneraattori?

Posted: Fri Mar 18, 2011 4:03 pm
by valscion
TukeKoodi wrote:Kiitos, laitoin kaikki muuttujat paitsi tunnus_kirjain For...Next loopin sisään ja nyt toimii!
Hienoa kuulla :)

Jos muuten haluat saada koodistasi tuon Select...Case rakenteen pois niin se onnistuu, sillä tuon kirjaimen/numeron valitseminen onnistuisi myös yksinkertaisesti käyttämällä ASCII-arvoja (kts. ASCII-taulukko). Teet tarkistuksen että onko tunnus-muuttuja pienempi kuin 10 ja jos on niin laitetaan se suoraan tunnus_kirjain-muuttujaan. Jos taas se on suurempi kuin 10 niin valitaan jollain tavalla tuolta ASCII-taulukosta oikea kirjain käyttämällä Chr-funktiota (esim. Chr(65) = A).