WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   asp.net C# kontroll av personnummer. (https://www.wn.se/forum/showthread.php?t=1055151)

naak2803 2012-09-27 21:02

asp.net C# kontroll av personnummer.
 
Hej,

Jag undrade ifall någon där ute har c# .net script för att kontrollera ifall ett personnummer är rätt eller felaktig... hör av dig ifall du är ville att dela med dig av scriptet.

Kimpo 2012-09-27 21:40

Testa detta Regex:

Kod:

\d{6}-\d{4}

yakuzaemme 2012-09-27 22:09

Citat:

Ursprungligen postat av naak2803 (Inlägg 20451747)
Hej,

Jag undrade ifall någon där ute har c# .net script för att kontrollera ifall ett personnummer är rätt eller felaktig... hör av dig ifall du är ville att dela med dig av scriptet.

Jag har ett egetgjort som först kontrollerar om personnummer är äkta, och sedan returnerar förnamn, efternamn, adress, postnummer och kön. Dessutom kollar skriptet om personnummer finns, det finns ju program som genererar fram ett personnummer som ej finns.

Till rätt person kan jag även lägga till att den ska ta fram telefonnummber (har koden redo för detta). Olika prioriteringar (mobilnummer, hem, jobb osv) och en mängd variabler som spelar roll. Får inte alltid fram telefonnummer (eller rätt telenummer), men bra att använda om man vill verifiera automatiskt att användaren telefonnummer är korrekt.


Har detta till C# och PHP

Hör av dig om du är intresserad av det.

Conny Westh 2012-09-27 22:37

Citat:

Ursprungligen postat av yakuzaemme (Inlägg 20451757)
Jag har ett egetgjort som först kontrollerar om personnummer är äkta, och sedan returnerar förnamn, efternamn, adress, postnummer och kön. Dessutom kollar skriptet om personnummer finns, det finns ju program som genererar fram ett personnummer som ej finns.

Till rätt person kan jag även lägga till att den ska ta fram telefonnummber (har koden redo för detta). Olika prioriteringar (mobilnummer, hem, jobb osv) och en mängd variabler som spelar roll. Får inte alltid fram telefonnummer (eller rätt telenummer), men bra att använda om man vill verifiera automatiskt att användaren telefonnummer är korrekt.


Har detta till C# och PHP

Hör av dig om du är intresserad av det.

Det verkar intressant, vilken webbtjänst använder du för att slå upp namn och adressuppgifterna?

yakuzaemme 2012-09-27 23:26

Citat:

Ursprungligen postat av ConnyWesth (Inlägg 20451760)
Det verkar intressant, vilken webbtjänst använder du för att slå upp namn och adressuppgifterna?

Upplysning.se samt Ratsit, allt för att dubbelkolla så det stämmer. Finns liknande tjänster som tar betalt för varje returdata, dvs. att man skickar in ett personnummer via deras API och får tillbaka allt, men detta är egetutvecklat och helt gratis - framförallt väldigt snabbt, allt under en sekund.

Hurvida detta är acceptabelt eller ej enligt de tjänsterna jag kör emot är jag inte lika insatt i, om någon är intresserad så är det eran uppgift att ta reda på om detta är tillåtet eller inte :)

dAEk 2012-10-04 20:18

Söker man efter "personnummer programmering" på Google hittar man en tråd på sweclockers av alla ställen som innehåller exempel i både PHP och C#. Vet dock inte hur bra den koden funkar i verkligheten men när jag kikade såg det lovande ut. Man får testa lite om man vill vara säker men det borde iaf funka mycket bättre än naiva regex-lösningar som bara kontrollerar formatet och inte giltigheten.

Conny Westh 2012-10-04 22:30

Luhn-algoritmen eller moduls 10-metoden (som används för beräkning av checksiffran i bland annat personnummer) finns beskriven på Wikipedia för den som är intresserad: http://sv.wikipedia.org/wiki/Luhn-algoritmen.

Conny Westh 2012-10-04 22:48

Pseudocode:
Kod:

begin function getChecksiffra(text siffror) returns text
    integer summa = 0
    for (integer index = siffror.length to 0 step -1)
        integer siffervärde = value(siffror[index])
        // varannan gångras med 2 och varannan med 1...
        siffervärde = siffervärde * (((index+1) mod 2) +1)
        if (siffervärde>9)
            summa += siffervärde-9
            summa += siffervärde mod 10
        else
            summa += siffervärde
        endif
    end for
    text checksiffra = chr(10 - (summa mod 10))
    return checksiffra // som text
end function

text nr = "811218987"
text personnummer = nr + getChecksiffra(nr)
print "Personnummer: " + String.Format("999999-9999",personnummer))
// Personnummer: 811218-9876


Conny Westh 2012-10-04 23:20

ska man vara riktigt petig så metoden funkar oavsett längd på indatat så ska den se ut så här:

Pseudocode:
Kod:

begin function getChecksiffra(text siffror) returns text
    integer summa = 0
    integer paritet = siffror.length mod 2
    for (integer index = siffror.length to 0 step -1)
        integer siffervärde = value(siffror[index])
        // varannan gångras med 2 och varannan med 1...
        siffervärde = siffervärde * (((index+paritet) mod 2) +1)
        if (siffervärde>9)
            summa += siffervärde-9
            summa += siffervärde mod 10
        else
            summa += siffervärde
        endif
    end for
    text checksiffra = chr(10 - (summa mod 10))
    return checksiffra // som text
end function

text nr = "811218987"
text personnummer = nr + getChecksiffra(nr)
print "Personnummer: " + String.Format("999999-9999",personnummer))
// Personnummer: 811218-9876


Conny Westh 2012-10-21 08:04

Realiserade pseudokoden i C# och fixade några buggar samt renodlade strukturen något.

Här är tre filer för C# med kontroll av checksiffran enligt modulus-10-metoden. Jag har medvetet inte lagt in kontroller av datum i personnummer, det gör att klassen även kan användas för orgnr, GD-nummer m.m.

Men vill man ha det så är det lätt att lägga till ytterligare kontroller i isValidate-metoden så slår det igenom direkt.

Jag har valt att göra klassen enkel så den kan anpassas till specifika behov snarare än att den blir för sträng för vissa användningsområden.

Finns det önskemål så kan jag lägga till mer kontroller, för det är enkelt i den struktur som finns nu.

Jag la upp en separat testklass: PersonnummerTest.cs så blir det enkelt att kontrollera om klassen gör vad den ska göra, testa med ditt eget personnummer så får du se....

Filen Program.cs är där hela programmet startar i C#.

Klassen Personummer.cs är byggd generellt så den kan användas oavsett om du kör Console, Winform eller Webform, eller någon annan typ av användargränssnitt, all gränssnittskod ligger i klassen PersonnummerTest.cs.

Håll till godo och slit den med hälsan.... :-)


Kod:

////////////////////////////////////////////////////
// File........: Personnummer.cs
// Author......: Conny Westh, Vallentuna, Sweden
// EMail.......: [email protected]
// Date Created: 2012-10-21
// Licence.....: Copyright as follows:
// You may use this code at your own risk,
// This code is provided as is!
////////////////////////////////////////////////////
// Klassen kan användas för att skapa eller
// kontrollera checksiffra i personnummer
// Checksiffran beräknas med moudulus-10-metoden.
// För att se hur klassen kan användas finns
// exempel i filen PersonnummerTest.cs
////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Personnummer
{
        public class Personnummer
        {
                private string PersNr;
                public Personnummer()
                {
                }
               
                public Personnummer(string PersNr)
                {
                        if (isValidate(PersNr))
                        {
                                this.PersNr = PersNr;
                        }
                        else
                        {
                                throw new ArgumentException(String.Format("Felaktigt personnummer: {0}.",PersNr));
                        }
                }
               
                public Boolean isValidate(string PersNr)
                {
                        Boolean ret=false;
                        string pnr9digits = String.Format("{0}{1}",PersNr.Substring(0,6),PersNr.Substring(7,3));
                        if (PersNr.Substring(10, 1).Equals(calculateCheckDigit(pnr9digits)))
                        {
                                ret = true;
                        }
                        return ret;
                }

                public string calculateCheckDigit(string strDigits)
                {
                        //text nr = "811218987"
                        //text personnummer = nr + calculateCheckDigit(nr)
                        //print "Personnummer: " + String.Format("999999-9999",personnummer))
                        // Personnummer: 811218-9876

                        List<int> digits = new List<int>();
                        foreach (char c in strDigits.ToArray())
                        {
                                digits.Add(int.Parse(String.Format("{0}",c)));
                        }
                        return String.Format("{0}", calculateCheckDigit(digits));
                }

                public int calculateCheckDigit(List<int> digits)
                {
                        int digitSum = 0;
                        int checkDigit = 0;
                        int paritet = digits.Count % 2;
                        for (int index = digits.Count-1; index >= 0; index--)
                        {
                                int digitValue = digits[index];
                                // varannan multipliceras med 2 och varannan med 1...
                                digitValue = digitValue * (((index + paritet) % 2) + 1);
                                if (digitValue>9)
                                {
                                        digitSum += digitValue / 10;
                                        digitSum += digitValue % 10;
                                }
                                else
                                {
                                        digitSum += digitValue;
                                }
                        }
                        checkDigit = (10 - (digitSum % 10)) % 10 ;
                        return checkDigit;
                }

                public override string ToString()
                {
                        return this.PersNr;
                }
        }
}

Kod:

////////////////////////////////////////////////////
// File........: PersonnummerTest.cs
// Author......: Conny Westh, Vallentuna, Sweden
// EMail.......: [email protected]
// Date Created: 2012-10-21
// Licence.....: Copyright as follows:
// You may use this code at your own risk,
// This code is provided as is!
////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Personnummer
{
        public class PersonnummerTest
        {
                public PersonnummerTest()
                {
                }
                public void Test()
                {
                        Console.WriteLine();
                        Console.WriteLine("----- Test Suite for valid Personnummer -----");
                        List<Personnummer> pnrList = new List<Personnummer>();
                        List<string> pnrStringList = new List<string>();

                        try
                        {
                                Console.WriteLine();
                                Console.WriteLine("Add all valid Personnummer.");
                                pnrStringList.Add("010101-0106");
                                pnrStringList.Add("020202-0202");
                                pnrStringList.Add("030303-0308");

                                pnrStringList.Add("101010-1010");
                                pnrStringList.Add("111111-1116");
                                pnrStringList.Add("121212-1212");

                                pnrStringList.Add("811218-9876");

                                pnrStringList.Add("010101+0106");
                                pnrStringList.Add("020202+0202");
                                pnrStringList.Add("030303+0308");

                                pnrStringList.Add("101010+1010");
                                pnrStringList.Add("111111+1116");
                                pnrStringList.Add("121212+1212");

                                pnrStringList.Add("811218+9876");
                               
                        }
                        catch (Exception ex)
                        {
                                Console.WriteLine("Personnr pnrStringList: FEL: {0}.", ex.Message);
                        }

                        try
                        {
                                Console.WriteLine();
                                Console.WriteLine("Test all Personnummer.");
                                foreach (string pnr in pnrStringList)
                                {
                                        try
                                        {
                                                pnrList.Add(new Personnummer(pnr));
                                                //Console.WriteLine("Personnr: {0}.", pnr);
                                        }
                                        catch (ArgumentException ex)
                                        {
                                                Console.WriteLine("Personnr pnrList.Add: {0} FEL: {1}.", pnr, ex.Message);
                                        }
                                        catch (Exception ex)
                                        {
                                                Console.WriteLine("Personnr pnrList.Add: {0} FEL: {1}.", pnr, ex.Message);
                                        }
                                }
                        }
                        catch (Exception ex)
                        {
                                Console.WriteLine("Personnr: pnrList FEL: {0}.", ex.Message);
                        }

                        Console.WriteLine();
                        Console.WriteLine("List all valid Personnummer.");
                        foreach (Personnummer pnr in pnrList)
                        {
                                Console.WriteLine("Personnr: {0}.", pnr);
                        }
                }
        }
}

Kod:

////////////////////////////////////////////////////
// File........: Program.cs
// Author......: Conny Westh, Vallentuna, Sweden
// EMail.......: [email protected]
// Date Created: 2012-10-21
// Licence.....: Copyright as follows:
// You may use this code at your own risk,
// This code is provided as is!
////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Personnummer
{
        public class Program
        {
                static void Main(string[] args)
                {
                        PersonnummerTest pnrTest = new PersonnummerTest();
                        pnrTest.Test();
                        Console.ReadKey();
                }
        }

}


yakuzaemme 2012-10-21 21:05

Citat:

Ursprungligen postat av ConnyWesth (Inlägg 20453465)
Kod...


Du gör det så mycket svårare och mer komplicerat än vad det är. Dessutom har dendär inget kontroll över falska personuppgifter, som man kan få tag på genom en enkel google-sökning. Med andra ord är en sådan kontroll värdelös om den ska användas mot riktiga användare.

Ska den bara användas inom exempelvis företaget för att registera sig, fine. Kan skriva ihop en liten kodsnutt senare ikväll och posta här, på en lösning jag tycker är bättre.

jonny 2012-10-22 18:45

Det är väl en ganska bra första kontroll att validera personnumret så att det är rätt antal siffror och rätt checksiffra.

Det är ju inte särskilt svårt att få fram personuppgifter om man vill registrera sig som någon annan.

tartareandesire 2012-10-22 18:51

Citat:

Ursprungligen postat av jonny (Inlägg 20453560)
Det är väl en ganska bra första kontroll att validera personnumret så att det är rätt antal siffror och rätt checksiffra.

Det är ju inte särskilt svårt att få fram personuppgifter om man vill registrera sig som någon annan.

Exakt, det handlar mer om hur många man lyckas filtrera bort ifall det är värt besväret. Att validera personnumret är mer att betrakta som en extra service för besökaren än ett bra skydd mot bedragare.

Conny Westh 2012-10-22 22:33

Jag ser det som två olika valideringar dels att kontrollera att personnummer/orgnr uppfyller de grundläggande kraven som jonny skrev och dels ett helt annat krav om att en person finns i ett annat register.

slår man exempelvis upp ett personnummer mot upplysning.se så får du inte med perosner som är under 16 år, du får inte heller med personer med skyddade personuppgifter. Samt att du absolut måste ha uppkoppling mot internet när du kör kontrollen, dessutom måste tjänstens system vara uppe och rulla samtidigt.

Den första enkla kontrollen som jag bidro med källkod till är avsedd att användas som ett första filter för att slippa rena skrivfel, som är de vanligaste felen, säkerligen över 95%.

Men den kod jag laddade upp är även skriven för att göra den enkelt för de här på WN som inte är så haj på kodning i C# och som vill ha en hyfsad grundstruktur att bygga på egna kontroller av indata. Jag har medvetet låtit bli att göra koden "fullkomlig" då det sätter en del begränsningar av användningsområdet.

Checksiffram brukar vara knepig för de flesta newbies att få till en hyfsad kontroll på, men den är väldigt viktig i algoritmen.

Jag är absolut positiv till om andra vill bygga vidare och komplettera med egna tillägg.

Flera saker kan kompletteras:

- Kolla längd på input data
- Filtrera bort alla tecken utom 0-9 + och -
- Kolla att det är ett giltigt datum angivet
.
.
.

Man kan givetvis "optimera" koden för bättre prestanda eller mindre minnesanvändning, men det finns knappast någon anledning i 99,9999 procent av användningstillfällena.

hnn 2012-10-22 22:58

Personnummer är numera 12 siffror.

http://www.skatteverket.se/download/...08svartvit.pdf

yakuzaemme 2012-10-22 23:29

Hittade denna funktion liggandes på burken. Vad jag menade med din kod Conny var inte att den var dålig eller dylikt men att den var allt för avancerad till vad den skulle bli använd till, om det bara var för att kontrollera skrivfel och dylikt.

Skulle man använda det på en hemsida eller dylikt, säg en webshop, så vill man ha mer bekräftelse än att lite matematik stämmer.

Kod:

private static bool isValid(string n)
        {
            n = n.Trim(); if (n.Contains('-')) n = n.Replace("-", "");
            if (n.Length > 10) n = n.Substring(2, 10);

            Int32 chkSum = 0;
            for (Int32 i = 0; i < n.Length; i++)
            {
                Int32 num = int.Parse(n[i].ToString());
                Int32 addSum = 0;
                if (i % 2 == 0) { addSum = num * 2; if (addSum > 9) addSum -= 9;  }
                else addSum = num;

                chkSum += addSum;
            }
            return (chkSum % 10 == 0);
        }


hnn 2012-10-22 23:35

Du kan inte säga att "-" enbart ska gälla eftersom "+" är giltig för personer som fyllt 100 år.
Även personnummer utan -+ är giltiga.

yakuzaemme 2012-10-22 23:38

Citat:

Ursprungligen postat av hnn (Inlägg 20453581)
Du kan inte säga att "-" enbart ska gälla eftersom "+" är giltig för personer som fyllt 100 år.
Även personnummer utan -+ är giltiga.

Har jag sagt något annat?

Det fungerar men skulle inte använda det i någon liveprodukt, vilket jag hoppas du och TS förstår. Syftet med ett forum som detta är inte att vi ska spoonfeeda med kod utan att ge dom en bas att jobba på. Detta fungerar somsagt, man skulle kunna lägga in mer kontroller och dylikt, ja.


Alla tider är GMT +2. Klockan är nu 21:28.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson