Gå til innhold

[Løst] Validering av fødselsnummer?


Anbefalte innlegg

Hei. Studerer for øyeblikket Datateknikk på høyskole og holder på med en del java programmering. Nylig fikk jeg utlevert en oppgave der jeg skal skrive et program som skal validere et innskrevet fødsel/persons nummer.

 

Det jeg lurer litt på er hvordan metoden for valideringen skal skrives?

et hint fra oppgaven er å bruke:

public static boolean sjekkFødselsnummer( long number)

 

(de råe formlene for fødselsnummerene her:

http://no.wikipedia.org/wiki/F%C3%B8dselsnummer)

 

~Takker for svar.

Lenke til kommentar
Videoannonse
Annonse

Noe slikt:

(1. Sjekk om fødselsnummerets 6 første siffere er gyldige (om dette er en gyldig dato, litt utfordring her er at du kun har to siffer for årstallet))

2. Hvis (1) OK (eller om du blåser i om datoen er gyldig), sjekk om det nest siste sifferet er korrekt (hint: bruke en array med k1-vektene du finner på nettsiden du linket til, og loop gjennom de 9 første sifrene av fødselsnummeret)

3. Hvis (2) OK, sjekk om det siste sifferet er korrekt på samme måte som i (2), men bruk nå en ny array med k2-vektene og sjekk de 10 første sifrene av fødselsnummeret.

 

Det skal heller ikke så mye ekstra til for å sjekke om fødselsnummeret er et gyldig D-nummer, H-nummer eller FH-nummer...

Endret av jonny
  • Liker 1
Lenke til kommentar

Skuddår klarer du ikke ta høyde for fordi kun to siffer i årstallet er lagret. (Skuddår skjer i årstall delelig med 4, men ikke hvis det også er delelig med 100 -med mindre- de også er delelig med 400)

 

Jeg tenkte at det burde være lett å bruke en regex for å sjekke om formatet var rett. Så skulle jeg ta høyde for D- og H-nummer og måneder med ulik lengde, og så gikk det en stund og det ble det ikke akkurat så lett som jeg hadde opprinnelig forestillt meg...

 

Nå ble nok dette langt utenfor det du hadde tenkt, men uantsett så tror jeg denne er ca riktig:

 

private static String FNUM =
"\\b((((0[1-9]|[12]\\d|3[01])([04][13578]|[15][02]))|" + // Måneder med 31 dager, tillater H nummer i 3. siffer
		"((0[1-9]|[12]\\d|30)([04][469]|[15]1))" + // samme, 30 dager
		"|((0[1-9]|[12]\\d)([04]2)))" + // samme, februar
		"|" + "((([0-7][1-9]|[12]\\d|3[01])(0[13578]|1[02]))|" + // Måneder med 31 dager, D-nummer
		"(([0-7][1-9]|[12]\\d|30)(0[469]|11))|" + // samme, 30 dager
		"(([0-7][1-9]|[12]\\d)(02))))" + // samme, februar
		"\\d{7}\\b"; // år (2) + personnummer (5) kan være alle tall
private static boolean sjekkFodselsnummer(long nummer) {
	return Long.toString(nummer).matches(FNUM) && k1(nummer) && k2(nummer);
}
private static boolean k2(long nummer) {
	// TODO
	return true;
}
private static boolean k1(long nummer) {
	// TODO
	return true;
}

Lenke til kommentar

Her er et alternativ til regex-opplegget ovenfor for å sjekke hva slags fødselsnummer det er. Metoden sjekker om datoen er en gyldig dato (hvis det ikke er et FH-nummer), men ikke om kontrollsifferne er riktige.

 

public static enum BirthNumberType {
 INVALID_BIRTH_NUMBER,
 NORMAL_BIRTH_NUMBER,
 D_NUMBER,
 H_NUMBER,
 FH_NUMBER
}

public static BirthNumberType birthNumberType(long bno) {
 BirthNumberType result = BirthNumberType.NORMAL_BIRTH_NUMBER;
 if (bno >= 80000000000L) {
   return BirthNumberType.FH_NUMBER;
 }
 int day = (int)(bno / 1000000000);
 int month = (int)((bno / 10000000) % 100);
 int year = (int)((bno / 100000) % 100) + 2000;

 if (day > 40) {
   day -= 40;
   result = BirthNumberType.D_NUMBER;
 }
 else if (month > 40) {
   month -= 40;
   result = BirthNumberType.H_NUMBER;
 }

 Calendar cal = Calendar.getInstance();
 cal.set(year, month-1, day);
 if (cal.after(Calendar.getInstance())) {
   year -= 100;
   cal.set(year, month-1, day);
 }
 if (cal.get(Calendar.YEAR) == year
     && cal.get(Calendar.MONTH) == (month-1)
     && cal.get(Calendar.DATE) == day) {
   return result;
 }
 else {
   return BirthNumberType.INVALID_BIRTH_NUMBER;
 }
}

 

Skuddår vil fungere så lenge fødselsnummeret gjelder en person som er yngre enn 100 år.

Endret av jonny
Lenke til kommentar

“If you aren’t extremely proficient with regular expressions right now, then you should drop everything and go become proficient with them. I bet I use regular expressions on 350 days out of every year: in my editor, on the command-line, in my code — anywhere that using one would save me time or make my code clearer. Oh, how it hurts to think about all the so-called “programmers” out there who don’t know how to use regexps. Argh.”

 

http://blog.kjempekj...11/12/23/regex/

Endret av torbjørn marø
Lenke til kommentar

Men å løse dette problemet med regex når en skal hjelpe en student med noe blir litt dumt.

Dessuten har et personnr kontrollsifre en må regne ut og se om matcher for å validere personnummeret.

 

Da jeg hadde en lignende oppgave så vi bare på "vanlige" fødselsnumre, og så var poenget å sjekke om de første 6 siffrene var en gyldig dato, og de 5 siste gyldige mtp kontrollnummer (og kjønn).

Lenke til kommentar

Regex var ganske fraværende på skolen når jeg gikk der, og det var grunnen til at jeg tenkte å foreslå en sånn løsning. Som jeg påpekte så ble den for omfattende for dette tilfellet, så det ble mer en test for å se om jeg fikk det til :)

 

 

F.eks url-rewrite på webservere, mønstergjenkjenning og tekstmanipulering (f.eks bytte tab til spaces for å poste kode på forumet her) er nesten umulig å gjennomføre uten regex, så påstanden om at det skaper flere problemer enn det løser er jeg veldig uenig i.

Lenke til kommentar

Jeg bruker regex til masse, men det er fort at de som først har lært regexp syns det er en fin hammer, og at alt ser ut som spiker.

 

Det var vel ikke så mye en påstand om at regex skaper problemer som et kjent sitat som jeg syns passet godt i dette tilfellet, og ofte ellers, fordi mange velger å løse problemer som ikke er egnet til det med regex.

Lenke til kommentar

Dette er hele oppgaven jeg har fått utlevert. Og ikke får å få en rask fasit, men hvis jeg skulle løse dette gjennom regex, hvordan skulle jeg ha skrevet dette fra start til stop?

 

P,s(dette er ikke noe tentamens oppgave eller noe på den måten, dette er mer en øvingsoppgave som er til for at vi skal lære oss å programmere. Og jo flere måter jeg lærer å løse ting på, jo raskere lærer jeg å gjøre ting mer effektivt :) )

 

Oppgave 3: Validering av fødselsnummer

Les om oppbyggingen av fødselsnummer på Wikipedia, http://no.wikipedia.org/wiki/F%C3%B8dselsnummer

Skriv en metode som sjekker et fødselsnummer for gyldig oppbygging, metoden

returnerer true for et gyldig fødselsnummer og false for et ugyldig nummer.

Benytt følgende metode hode:

public static boolean sjekkFødselsnummer( long number)

For eksempel, sjekkFødselsnummer (2412200012345) returnerer false.

Skriv et testprogram som spør brukeren om å gi inn et fødselsnummer og skriv resultatet

av valideringen ut på skjermen, spør deretter brukeren om han ønsker validere flere

fødselsnummer. Benytt JOptionPane klassen for dialog med brukeren.

Lenke til kommentar

... fordi mange velger å løse problemer som ikke er egnet til det med regex.

Problemet er nok først og fremst at folk ikke kan det godt nok.

Tja, ingen tvil om at det er mange som ikke kan regex godt nok, men det er kanskje like mange som ikke kan programmere "godt nok" til å vite hvilke verktøy som skal brukes til hvilke problemer. Ta problemet det her er snakk om som eksempel: Det er parsing av data, så da tenker mange at regex passer fint. Men det er en tekststreng/tall av fast lengde med veldig lite variasjon som mye bedre lar seg løse uten regex. Dette eksempelet er lite og trivielt, men strukturelt er det, etter min mening, av en klasse problemer som er uegnet for regex. Med uegnet for regex mener jeg at koden blir enklere (ikke nødvendigvis kortere), mer tydelig og vedlikeholdsvennlig hvis du holder deg unna regex.

Lenke til kommentar

Men det er en tekststreng/tall av fast lengde med veldig lite variasjon som mye bedre lar seg løse uten regex. Dette eksempelet er lite og trivielt, men strukturelt er det, etter min mening, av en klasse problemer som er uegnet for regex. Med uegnet for regex mener jeg at koden blir enklere (ikke nødvendigvis kortere), mer tydelig og vedlikeholdsvennlig hvis du holder deg unna regex.

Tja, kan kanskje med fordel bruke Regex til å dele opp personnummeret for så å validere de forskjellige delene med vanlig kode?

Lenke til kommentar

Men det er en tekststreng/tall av fast lengde med veldig lite variasjon som mye bedre lar seg løse uten regex. Dette eksempelet er lite og trivielt, men strukturelt er det, etter min mening, av en klasse problemer som er uegnet for regex. Med uegnet for regex mener jeg at koden blir enklere (ikke nødvendigvis kortere), mer tydelig og vedlikeholdsvennlig hvis du holder deg unna regex.

Tja, kan kanskje med fordel bruke Regex til å dele opp personnummeret for så å validere de forskjellige delene med vanlig kode?

 

Joa, men det holder med noe sånt som å fjerne alt som ikke er siffer, sjekke om lengden er 11, og så dele etter posisjon - så det eneste regulære uttrykket blir noe sånt som fNummer.replace("[^0-9]", "") .

Lenke til kommentar

Men det er en tekststreng/tall av fast lengde med veldig lite variasjon som mye bedre lar seg løse uten regex. Dette eksempelet er lite og trivielt, men strukturelt er det, etter min mening, av en klasse problemer som er uegnet for regex. Med uegnet for regex mener jeg at koden blir enklere (ikke nødvendigvis kortere), mer tydelig og vedlikeholdsvennlig hvis du holder deg unna regex.

Tja, kan kanskje med fordel bruke Regex til å dele opp personnummeret for så å validere de forskjellige delene med vanlig kode?

 

Joa, men det holder med noe sånt som å fjerne alt som ikke er siffer, sjekke om lengden er 11, og så dele etter posisjon - så det eneste regulære uttrykket blir noe sånt som fNummer.replace("[^0-9]", "") .

Jeg ville sagt at all tekst som inneholder noe annet enn utelukkende 11 siffer ikke er et personnummer.

Lenke til kommentar

Men det er en tekststreng/tall av fast lengde med veldig lite variasjon som mye bedre lar seg løse uten regex. Dette eksempelet er lite og trivielt, men strukturelt er det, etter min mening, av en klasse problemer som er uegnet for regex. Med uegnet for regex mener jeg at koden blir enklere (ikke nødvendigvis kortere), mer tydelig og vedlikeholdsvennlig hvis du holder deg unna regex.

Tja, kan kanskje med fordel bruke Regex til å dele opp personnummeret for så å validere de forskjellige delene med vanlig kode?

 

Joa, men det holder med noe sånt som å fjerne alt som ikke er siffer, sjekke om lengden er 11, og så dele etter posisjon - så det eneste regulære uttrykket blir noe sånt som fNummer.replace("[^0-9]", "") .

Jeg ville sagt at all tekst som inneholder noe annet enn utelukkende 11 siffer ikke er et personnummer.

 

Absolutt ikke? Hvis folk dytter inn whitespace rundt eller inni (for å gruppere), eller eventuelt separerer dato-delen med (skrå-)streker eller kolon eller underscores eller semikolon eller teksten "og neste siffer er" - så er det fortsatt trivielt å sjekke om det ser ut som et personnummer (sjekksum, plausibel dato). Å forkaste noe man lett kan tolke er bare å gjøre det vanskeligere for brukeren fordi man kan, og det er dårlig UI-design. :)

 

edit: Det sagt, for denne oppgaven er jeg tilbøyelig til å være enig med deg. Det er forskjell på "se om brukeren har skrevet (noe vi kan tolke som) et gyldig fødselsnummer" og "sjekk om denne strengen er et korrekt fødselsnummer" - og de vil antageligvis ha sistnevnte.

Endret av Djn
Lenke til kommentar

Absolutt ikke? Hvis folk dytter inn whitespace rundt eller inni (for å gruppere), eller eventuelt separerer dato-delen med (skrå-)streker eller kolon eller underscores eller semikolon eller teksten "og neste siffer er" - så er det fortsatt trivielt å sjekke om det ser ut som et personnummer (sjekksum, plausibel dato). Å forkaste noe man lett kan tolke er bare å gjøre det vanskeligere for brukeren fordi man kan, og det er dårlig UI-design. :)

 

edit: Det sagt, for denne oppgaven er jeg tilbøyelig til å være enig med deg. Det er forskjell på "se om brukeren har skrevet (noe vi kan tolke som) et gyldig fødselsnummer" og "sjekk om denne strengen er et korrekt fødselsnummer" - og de vil antageligvis ha sistnevnte.

Er enig med deg i at en må tillate mye, men en valideringsfunksjon må aldri gjøre noe annet enn å validere, som du påpeker. Hvis du skal fjerne ekstra-tegn så bør det skje i en utenforliggende funksjon.

 

Jeg mener valideringsfunksjoner ikke skal gi exceptions og ikke mutere state på noen som helst måte.

Endret av GeirGrusom
  • Liker 1
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...