Avatar billede tri Nybegynder
11. juli 2002 - 13:03 Der er 31 kommentarer og
2 løsninger

CPR validering

Jeg skal bruge en metode som kan validerer et cprnr.

Er der nogen som kan hjælpe mig igang med det?
Avatar billede disky Nybegynder
11. juli 2002 - 13:16 #1
Her er et eksempel i VB som du nemt kan omskrives:
Function check_cpr(ByVal Cprnr)
Dim Tal, I, Sum, Rest, Kontroltal, Resultat
Cprnr = Cprnr & " "
If Val(Cprnr) = 0 Or Len(Cprnr) < 10 Then
    Resultat = "Mangler data"
Else
    Tal = "432765432"
    For I = 1 To 9
          Sum = Sum + Val(Mid(Cprnr, I, 1)) * Val(Mid(Tal, I, 1))
    Next
    Rest = Sum Mod 11
    Kontroltal = 11 - Rest
    If Rest = 0 Then Kontroltal = 0
    Resultat = "Fejl"
    If Kontroltal = 10 Then Resultat = "Dato og/eller Løbenummerfejl"
    If Kontroltal = Val(Mid(Cprnr, 10)) Then Resultat = "OK"
End If
check_cpr = Resultat
End Function
Avatar billede disky Nybegynder
11. juli 2002 - 13:23 #2
Her er et eksempel i VB som du nemt kan omskrives:

Metoden Mid() hedder subString() i java


Function check_cpr(ByVal Cprnr)
Dim Tal, I, Sum, Rest, Kontroltal, Resultat
Cprnr = Cprnr & " "
If Val(Cprnr) = 0 Or Len(Cprnr) < 10 Then
    Resultat = "Mangler data"
Else
    Tal = "432765432"
    For I = 1 To 9
          Sum = Sum + Val(Mid(Cprnr, I, 1)) * Val(Mid(Tal, I, 1))
    Next
    Rest = Sum Mod 11
    Kontroltal = 11 - Rest
    If Rest = 0 Then Kontroltal = 0
    Resultat = "Fejl"
    If Kontroltal = 10 Then Resultat = "Dato og/eller Løbenummerfejl"
    If Kontroltal = Val(Mid(Cprnr, 10)) Then Resultat = "OK"
End If
check_cpr = Resultat
End Function
Avatar billede disky Nybegynder
11. juli 2002 - 13:33 #3
Hejsa

Jeg har ikke lige noget Java program, men dette VB program gør det, og det skulle være meget nemt at omskrive til java,
VB's Mid() metode hedder subString() i java

Function check_cpr(ByVal Cprnr)
Dim Tal, I, Sum, Rest, Kontroltal, Resultat
Cprnr = Cprnr & " "
If Val(Cprnr) = 0 Or Len(Cprnr) < 10 Then
    Resultat = "Mangler data"
Else
    Tal = "432765432"
    For I = 1 To 9
          Sum = Sum + Val(Mid(Cprnr, I, 1)) * Val(Mid(Tal, I, 1))
    Next
    Rest = Sum Mod 11
    Kontroltal = 11 - Rest
    If Rest = 0 Then Kontroltal = 0
    Resultat = "Fejl"
    If Kontroltal = 10 Then Resultat = "Dato og/eller Løbenummerfejl"
    If Kontroltal = Val(Mid(Cprnr, 10)) Then Resultat = "OK"
End If
check_cpr = Resultat
End Function
Avatar billede europe Nybegynder
11. juli 2002 - 13:36 #4
Der skal bruges et modus11 check til det.. Jeg har ikke lige metoden ved hånden men den kan findes frem senere....
Avatar billede bearhugx Nybegynder
11. juli 2002 - 13:37 #5
Jeg lavede for et år siden en metode, som kunne finde alle CPR på en given fødselsdag....


Den kan findes på
http://www.stud.tietgen.dk/edb/dm997/dm99724/index.htm

Jeg prøver lige at kigge i mine gemmer om der også er en validerings-metode

/Søren
Avatar billede disky Nybegynder
11. juli 2002 - 13:37 #6
okay nu tilter eksperten da helt,

jeg postede en gang, siden reloade efter LANG tid uden det var kommet med jeg prøver igen samme resultat, og igen og vupti nu er det her 3 gange.
Avatar billede bearhugx Nybegynder
11. juli 2002 - 13:42 #7
Ja.. Jeg er da heldig, at mit indlæg kun kom på en gang ...
/Søren
Avatar billede disky Nybegynder
11. juli 2002 - 13:53 #8
tri:

Jeg har lige omskrevet og testet det:
/*
* CPR.java
*
* Created on 11. juli 2002, 13:44
*/

/**
*
* @author  Reinke
* @version
*/
public class CPR
{
   
    /** Creates new CPR */
    public CPR()
    {
        String cpr="xxxxxxxxxx";
        System.out.println("Result = "+validateCpr(cpr));
    }
   
    private boolean validateCpr(String cpr)
    {
        if(cpr==null || cpr.length()!=10) return false;
       
        String tal = "432765432";
        int sum=0;
        int rest=0;
        int kontrolTal=0;
        for(int x=1;x<9;x++)
        {
            sum+=Integer.parseInt(cpr.substring(x,x+1))*Integer.parseInt(tal.substring(x,x+1));
        }

        rest = sum%11;
        kontrolTal = 11-rest;
        if(rest==0)
        {
            kontrolTal=0;
        }
        if(kontrolTal==10) return false;
        if(kontrolTal==Integer.parseInt(cpr.substring((9)))) return true;
        return false;
    }
   
    /**
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        new CPR();
    }
   
}


byt 'xxxxxxxxxx' ud med et cpr nummer så verificerer den det.

p.s. koden kan laves pænere men det virker.
Avatar billede disky Nybegynder
11. juli 2002 - 14:01 #9
bearhugx:
Jeg kunne ikke nære mig for at kigge på dine venners 13 tals opgave.
Den er ret spøjst på et par områder.

De beskriver kraftigt XP, men bryder samtidigt x-antal andre design patterns, f.eks. har de extremt hård kobling imellem design og funktionalitet osv.
Lad os håbe de har lært man IKKE blander Java kode og Html.

Ellers ser den fin ud (har kun skimmet den)
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:13 #10
Den er sandlig et kig værd...

Man skal huske på at de kun havde haft et 5-mdr kursus i Java først.. De kommer oprindeligt fra C++-verden...

Hvad angår blanding af HTML og Java , så var JSP ikke rigtigt kommet frem endnu - så de lavede servlets (den eneste serverside-tek., de kendte til på det tidspunkt) i stedet...

jeg må dog sige, at jeg også synes det var lidt problematisk at hardkode HTML'en - men det virkede...

/Søren...
Avatar billede disky Nybegynder
11. juli 2002 - 14:19 #11
bearhugx:
Jeg har skam også tænkt mig at læse den lidt nærmere.

Normalt er jeg imod XP da det ikke kan anvendes til den slags store projekter jeg normalt arbejder med, men til dele af de store produkter er det godt til.

Det er lidt mere bøvlet at adskille html og java i en servlet men man kan godt.

Det glæder mig du også synes det er problematisk :)
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:26 #12
Well... På det punkt er vi enige...

Nu ang. dette spørgsmål... Så har jeg lige med din kode fået påvist, at jeg går rundt med et falsk CPR# :-))

Sagt med andre ord - der er en bug i maskineriet... Jeg har ikke kunne finde den endnu ... Men leder dog...

:-)

Søren...

PS: hvis du skal have ekstra test-materiale til at teste metoden, kan jeg kun henvise til
http://www.stud.tietgen.dk/edb/dm997/dm99724/index.htm

Den virker :-))
Avatar billede disky Nybegynder
11. juli 2002 - 14:37 #13
mystisk,

jeg testede mit eget CPR det var okay, så ændrede jeg et tal så var det ikke okay.

Jeg har som sagt bare taget og lavet VB eksemplet til java, men hvad pokker der kan sagtens være sket en fejl :)
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:38 #14
Her er en CPR-validator, som jeg skulle mene virker

public class CPRValidator
{
  public static boolean isValid(String cpr)
  {
    // Test funktionel betingelse
    if( !(cpr!=null && cpr.length()==10))
      return false;

    // Test operationel interval
    long cprNr = Long.parseLong(cpr);
    if( !(cprNr> 101000000L && cprNr<3112999999L) )
      return false;

    // Lav cifferArrays
    int[] cprArray = toArray(cpr);
    int[] ktrlArray = toArray("4327654321");
   
    // Summér
    int sum=0;
    for(int pos=0; pos<10; ++pos)
      sum += cprArray[pos]*ktrlArray[pos];

    // Test Mod-11
    if(! ((sum%11)==0) )
      return false;

    return true;       
  }
   
  private static int[] toArray(String cpr)
  {
    int[] digitArray = new int[cpr.length()];
    for(int i=0; i<cpr.length(); ++i)
      digitArray[i] = Integer.parseInt(cpr.substring(i, +1));
    return digitArray;
  }
   
  public static void main( String args[] )
  { String cpr = "2011460030"; //  et gyldigt tilfældigt CPR
    System.out.println(" "+cpr+" valid? -> "+CPRValidator.isValid(cpr));
  }
}


/Søren
Avatar billede tri Nybegynder
11. juli 2002 - 14:42 #15
bearhugx:

Jeg kunne godt tænke mig selv at lave sådan en løbenr generator.
Er det noget du kan hjælpe med?
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:43 #16
Min  anelse har været, at du ikke har taget det 10. ciffer med i summeringen... Men selv når jeg retter for det, så virker det stadigvæk ikke...

Jeg har taget mig den frihed, at lave en sammenblanding af vores to koder, og den ser ud til at virke...

/Søren
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:44 #17
Kan du læse javascript-kode... ????

For så er koden på
  http://www.stud.tietgen.dk/edb/dm997/dm99724/diverse/CPR-gen.htm

/Søren
Avatar billede tri Nybegynder
11. juli 2002 - 14:47 #18
bearhugx:
Fint. Jeg havde ikke lige set at det var script.

Jeg får iøvrigt en "NumberFormatException"
når jeg afprøver din kode !
Avatar billede bearhugx Nybegynder
11. juli 2002 - 14:51 #19
aha... er det fordi du har cpr'et stående sådanne her "ddmmyy-lllk" ???

Det rigtige format på Sting'en skal være "ddmmyylllk" - dvs. uden noget bindestreg...

/Søren
:-)
Avatar billede tri Nybegynder
11. juli 2002 - 15:16 #20
Jeg har blot kopieret din kode:
Altså:
String cpr = "2011460030";

giver en NumberFormatException

Men det "virker" med 9 cifre....
Avatar billede bearhugx Nybegynder
11. juli 2002 - 15:25 #21
her er koden, hvor der bliver try-catchet- de steder, hvor en exception kunne forekomme...

public class CPRValidator
{
    public static boolean isValid(String cpr)
    {
        // Test funktionel betingelse
        if( !(cpr!=null && cpr.length()==10))
            return false;
       
        // Test operationel interval
        long cprNr = 0;
        try {
            cprNr = Long.parseLong(cpr);
        } catch(NumberFormatException nfEx)
        {    nfEx.printStackTrace();
        }
        if( !(cprNr> 101000000L && cprNr<3112999999L) )
            return false;
       
        // Lav cifferArrays
        int[] cprArray = toArray(cpr);
        int[] ktrlArray = toArray("4327654321");

        // Test NFEx
        if( cprArray==null )
            return false;
                   
        // Summér
        int sum=0;
        for(int pos=0; pos<10; ++pos)
            sum += cprArray[pos]*ktrlArray[pos];

        // Test Mod-11
        if(! ((sum%11)==0) )
            return false;
           
        return true;       
    }
   
    private static int[] toArray(String cpr)
    {
        try{
            int[] digitArray = new int[cpr.length()];
            for(int i=0; i<cpr.length(); ++i)
                digitArray[i] = Integer.parseInt(cpr.substring(i, i+1));
            return digitArray;
        } catch (NumberFormatException nfEx)
        {    nfEx.printStackTrace();
        }
        return null;
    }
   
    public static void main( String args[] )
    {    String cpr = "2011460030";
        System.out.println(" "+cpr+" valid? -> "+CPRValidator.isValid(cpr));
    }
}





Jeg undres... Her hos mig virker det :-/

/Søren
Avatar billede tri Nybegynder
11. juli 2002 - 15:33 #22
nu også her :-)
Avatar billede disky Nybegynder
11. juli 2002 - 15:38 #23
i min kode ret:
for(int x=1;x<9;x++)
til
for(int x=0;x<9;x++)

så godkender den også '2011460030' :-)

bearhugx: jeg synes dit hoppen frem og tilbage imellem String int[] osv er lidt omstændelig
Avatar billede disky Nybegynder
11. juli 2002 - 15:49 #24
her er en deluxe udgave, uden problemmer med exceptions (der er performance dårlige) eller mystisk konvertering osv.

Har godkendt de cpr-numre jeg kender:
/*
* CPR.java
*
* Created on 11. juli 2002, 13:44
*/

/**
*
* @author  thygesen
* @version
*/
public class CPR
{
   
    /** Creates new CPR */
    public CPR()
    {
        String cpr="2011460030";
        System.out.println("Result = "+validateCpr(cpr));
    }
   
    private boolean validateCpr(String cpr)
    {
        if(cpr==null || cpr.length()!=10) return false;
       
        char[] cprArray=cpr.toCharArray();

        for(int x=0;x<cprArray.length;x++)
        {
            if(!Character.isDigit(cprArray[x])) return false;
            cprArray[x]-='0';
        }

        char[] talArray={4,3,2,7,6,5,4,3,2,1};

        int sum=0;
        int kontrolTal=0;
        for(int x=0;x<9;x++)
        {
            sum+=cprArray[x]*talArray[x];
        }

        kontrolTal = 11-(sum%11);
        if(kontrolTal==11)
        {
            kontrolTal=0;
        }
        if(kontrolTal==10) return false;
        if(kontrolTal==(int)cprArray[9]) return true;
        return false;
    }
   
    /**
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        new CPR();
    }
}
Avatar billede bearhugx Nybegynder
11. juli 2002 - 15:50 #25
Det handler om én konvertering fra String til int[]..  i mit hoved giver det mere klarhed oppe i isValid()-metoden, hvis der ikke kommer "forstyrrende elementer" som f.eks. en parseInt og substring ind--

Jeg synes at det er mere klart i min kode, at det handler om at der er et cpr-ciffer, som bliver ganget med et kontrolciffer, og det er summen af det, som bliver mod11 testet....

Hvorimod jeg synes at din kode bærer for meget præg af tal/char-jonglering (parseInt og substring), i stedet for den "vigtige" ting - nemlig multiplikationen...


Selvfølgelig handler dette om _smag_ - og ikke andet ... Min kode laver næsten det samme som din ... Jeg vælger bare at gribe det an med en anden type, int,  istedet for String....

Som noget helt anden.. Hvad bruger du det "kontrolTal" til...

/Søren
Avatar billede bearhugx Nybegynder
11. juli 2002 - 15:58 #26
Ok .. Din nye tilgang med char[] i stedet for string er pænere :-) - det må jeg tilstå... -- Den vil med det samme blive brugt i min kode -- så slipper jeg også for nfEx'erne...

Min kode begynder (nok ikke overraskende) at ligne din... Jeg mangler bare at finde ud af, hvad du bruger det kontrolTal til...

Hvad er der så specielt ved [9] ????

/Søren
Avatar billede bearhugx Nybegynder
11. juli 2002 - 16:02 #27
-- Derudover, så må jeg være speciel.. Hvis man kun bruger "Mod11==0 test", så er mit CPR OK..

Men bruger man

kontrolTal = 11-(sum%11);
if(kontrolTal==11)
{
  kontrolTal=0;
}
if(kontrolTal==10) return false;
if(kontrolTal==(int)cprArray[9]) return true;
return false;

så vedtager man også med det samme, at alle CPR-nr, som består Mod 11 testen _SKAL_ have 0 som den andetsidste ciffer....  - Og det når man ikke langt med... (mit cpr har f.eks. ikke '0' i 9. position....)

/Søren
Avatar billede disky Nybegynder
11. juli 2002 - 16:07 #28
Søren:
Det er ikke ment som kritik, det jeg mener er at det er unødvendigt at lave konverteringen på den lidt omstændelige metode. Specielt brugen af try/catch er lidt dårlig rent performance mæssigt.

p.s. Jeg har lige ændret min så det kontroltal forsvinder, og bruger nu char[] istedet for, for at slippe for det String halløj, som jeg gerne vil indrømme er grimt. Men jeg konverterede jo også bare fra VB, jeg havde ikke selv lavet det :)

Men nedenstående version er optimeret og tunet lidt igen :))

nyeste optimerede version:

/*
* CPR.java
*
* Created on 11. juli 2002, 13:44
*/

/**
*
* @author  thygesen
* @version
*/
public class CPR
{
   
    /** Creates new CPR */
    public CPR()
    {
        String cpr="2803451977";
        System.out.println("Result = "+validateCpr(cpr));
    }
   
    private boolean validateCpr(String cpr)
    {
        if(cpr==null || cpr.length()!=10) return false;
       
        char[] cprArray=cpr.toCharArray();

        for(int x=0;x<cprArray.length;x++)
        {
            if(!Character.isDigit(cprArray[x])) return false;
            cprArray[x]-='0';
        }

        char[] talArray={4,3,2,7,6,5,4,3,2,1};

        int sum=0;
        for(int x=0;x<10;x++)
        {
            sum+=cprArray[x]*talArray[x];
        }

        if((sum%11)!=0) return false;
        return true;
    }
   
    /**
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        new CPR();
    }
   
}
Avatar billede bearhugx Nybegynder
11. juli 2002 - 16:20 #29
Tillykke Disky... Nu kan jeg afsløre, at vores CPR-valideringsmetoder (bortset fra variable-navngivning) er helt ens :-) *LOL*

Når ja.. og så det, at min er en static metode :-)..

I retrospect kan jeg også se, at især de exceptions der kom af konverteringerne ikke var så heldige... - men jeg brød mig ikke om dine parseInt/substring heller...

Men så er det jo godt at vi kan enes omkring char[] istedet :-))

Så er spørgsmålet nu bare om tri kan bruge nogle af vores anstrengelser :-))))

/Søren

PS : har du læst min kommentar i  http://www.eksperten.dk/spm/233191 ??
Avatar billede tri Nybegynder
11. juli 2002 - 16:43 #30
Jeg er skam meget tilfreds :-)

hvad med point fordelingen?

Hvad siger I ?
Avatar billede bearhugx Nybegynder
11. juli 2002 - 16:46 #31
Disky >>  50/50 eller ???
Avatar billede disky Nybegynder
11. juli 2002 - 16:51 #32
okay med mig
Avatar billede tri Nybegynder
11. juli 2002 - 16:53 #33
fint.

takker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester