Walidacja numerów PESEL, NIP, REGON w Javascript i PHP

Ulepszone funkcje z tego wpisu. Aktualnie funkcje sprawdzają także sumy kontrolne zawarte w tych numerach, na podstawie Wikipedii. Wystarczy przeanalizować kody

Odmiany funkcji w Javascript i PHP są w pełni zgodne, to znaczy że dadzą taką samą odpowiedź.

Aktualizacja 2017-05-02:

  • Zamieniłem polskie nazwy zmiennych na angielskie;
  • Funkcje od PESEL sprawdzają czy data jest poprawna, tj. miesiąc nie większy niż 12 i dzień miesiąca nie większy niż 31. To rozwiązuje problemy opisane w komentarzach. Dziękuję za zwrócenie uwagi i dziękuję Panu Krzysztofowi Grabania za propozycję rozwiązania problemu.
  • Poprawione wcięcia itp.
  • Dodane formularze, gdzie można sobie potestować jak działają funkcje w wersji JS. Wersje PHP: http://test.vt0.pl/v/

Oczywiście jeśli użytkownik będzie chciał, to i tak da radę wprowadzić nieprawdziwe dane, ale dzięki tej walidacji uchronimy się przed omyłkowym wpisaniem danych z błędami w formularzu.

1. Walidacja PESEL:

Kod PHP:

function validatepesel($pesel) {
    $reg = '/^[0-9]{11}$/';
    if(preg_match($reg, $pesel)==false)
        return false;
    else
    {
        $digits = str_split($pesel);
        if ((intval(substr($pesel, 4, 2)) > 31)||(intval(substr($pesel, 2, 2)) > 12))
            return false;
        $checksum = (1*intval($digits[0]) + 3*intval($digits[1]) + 7*intval($digits[2]) + 9*intval($digits[3]) + 1*intval($digits[4]) + 3*intval($digits[5]) + 7*intval($digits[6]) + 9*intval($digits[7]) + 1*intval($digits[8]) + 3*intval($digits[9]))%10;
        if($checksum == 0) 
            $checksum = 10;
        $checksum = 10 - $checksum;
            
        return (intval($digits[10]) == $checksum);
    }
}

Kod Javascript:

function validatepesel(pesel) {
    var reg = /^[0-9]{11}$/;
    if(reg.test(pesel) == false) 
        return false;
    else
    {
        var digits = (""+pesel).split("");
        if ((parseInt(pesel.substring( 4, 6)) > 31)||(parseInt(pesel.substring( 2, 4)) > 12))
            return false;
        
        var checksum = (1*parseInt(digits[0]) + 3*parseInt(digits[1]) + 7*parseInt(digits[2]) + 9*parseInt(digits[3]) + 1*parseInt(digits[4]) + 3*parseInt(digits[5]) + 7*parseInt(digits[6]) + 9*parseInt(digits[7]) + 1*parseInt(digits[8]) + 3*parseInt(digits[9]))%10;
        if(checksum==0) checksum = 10;
            checksum = 10 - checksum;

        return (parseInt(digits[10])==checksum);
    }
}

Test:

READY

2.Walidacja NIP

Kod PHP:

function validatenip($nip) {
    $nipWithoutDashes = preg_replace("/-/","",$nip);
    $reg = '/^[0-9]{10}$/';
    if(preg_match($reg, $nipWithoutDashes)==false)
        return false;
    else
    {
        $digits = str_split($nipWithoutDashes);
        $checksum = (6*intval($digits[0]) + 5*intval($digits[1]) + 7*intval($digits[2]) + 2*intval($digits[3]) + 3*intval($digits[4]) + 4*intval($digits[5]) + 5*intval($digits[6]) + 6*intval($digits[7]) + 7*intval($digits[8]))%11;

        return (intval($digits[9]) == $checksum);
    }
}

Kod Javascript:

function validatenip(nip) {
    var nipWithoutDashes = nip.replace(/-/g,"");
    var reg = /^[0-9]{10}$/;
    if(reg.test(nipWithoutDashes) == false) {
        return false;}
    else
    {
        var digits = (""+nipWithoutDashes).split("");
        var checksum = (6*parseInt(digits[0]) + 5*parseInt(digits[1]) + 7*parseInt(digits[2]) + 2*parseInt(digits[3]) + 3*parseInt(digits[4]) + 4*parseInt(digits[5]) + 5*parseInt(digits[6]) + 6*parseInt(digits[7]) + 7*parseInt(digits[8]))%11;
        
        return (parseInt(digits[9])==checksum);
    }
}

Test:

READY

3. Walidacja REGON (9-cyfrowy):

Kod PHP:

function validateregon9($regon) {
    $reg = '/^[0-9]{9}$/';
    if(preg_match($reg, $regon)==false)
        return false;
    else
    {
        $digits = str_split($regon);
        $checksum = (8*intval($digits[0]) + 9*intval($digits[1]) + 2*intval($digits[2]) + 3*intval($digits[3]) + 4*intval($digits[4]) + 5*intval($digits[5]) + 6*intval($digits[6]) + 7*intval($digits[7]))%11;
        if($checksum == 10) 
            $checksum = 0;

        return (intval($digits[8]) == $checksum);
    }
}

Kod Javascript:

function validateregon9(regon) {
    var reg = /^[0-9]{9}$/;
    if(!reg.test(regon)) 
        return false;
    else
    {
        var digits = (""+regon).split("");
        var checksum = (8*parseInt(digits[0]) + 9*parseInt(digits[1]) + 2*parseInt(digits[2]) + 3*parseInt(digits[3]) + 4*parseInt(digits[4]) + 5*parseInt(digits[5]) + 6*parseInt(digits[6]) + 7*parseInt(digits[7]))%11;
        if(checksum == 10) 
            checksum = 0;
        
        return (parseInt(digits[8])==checksum);
    }
}

Test:

READY

26 komentarzy do “Walidacja numerów PESEL, NIP, REGON w Javascript i PHP”

  1. thx,
    przydatne,
    polecam walidację zawsze po stronie serwera,
    jak już musi być w js to w 2 miejscach,
    bo zawsze się jakiś “spryciarz” może znaleźć wysyłający spreparowane posty.
    pozdr
    MK

  2. Przydały się w projekcie – dzięki! Pytanie tylko czemu nazwy zmiennych po polsku? 🙂 Po tym jak raz musiałem analizować kod od francuza zwracam na to uwagę.

  3. Też bym się przyczepił do nazw zmiennych i odrobinę do czystości kodu. Ale poza tym spoko 🙂
    Dzięki!

  4. Walidacja na pesel w Javascript. Pesel “82018228861” jest niepoprawny, jest niepoprawna data w peselu, dlatego funkcja powinna zwrócić false.

  5. PESEL ma wadę – można zamienić rok z dniem i walidacja przejdzie (via Wikipedia). Jednym z najprostszych sposób na naprawienie tego jest sprawdzenie cyfr 5 i 6 (w powyższym przykładzie będzie to 82) czy nie są przypadkiem większe od 31. W kodzie PHP tak to wygląda (należy umieścić w 7 linii):
    if (intval(substr($pesel, 4, 2)) > 31)
    return false;

  6. Próbuję zastosować skrypt do walidacji nip w Adobe Acrobat. Tworzę interaktywny formularz. Za każdym razem kiedy wpisuję błędny nip nic się nie dzieje. w polu mogę wpisać nawet słowa. Co zrobić żeby skrypt zaczął działać poprawnie?

    function validatenip(nip) {
    var nip_bez_kresek = nip.replace(/-/g,””);
    var reg = /^[0-9]{10}$/;
    if(reg.test(nip_bez_kresek) == false) {
    return false;}
    else
    {
    var dig = (“” nip_bez_kresek).split(“”);
    var kontrola = (6*parseInt(dig[0]) 5*parseInt(dig[1]) 7*parseInt(dig[2]) 2*parseInt(dig[3]) 3*parseInt(dig[4]) 4*parseInt(dig[5]) 5*parseInt(dig[6]) 6*parseInt(dig[7]) 7*parseInt(dig[8]));
    if(parseInt(dig[9])==kontrola)
    return true;
    else
    return false;
    }

    }

  7. Chciałbym zwrócić uwagę, ze walidacja PESEL jest bledna – otóż dla osób urodzonych po 2000 roku pesel wygląda nieco inaczej ( 20 do miesiąca). Mysle, ze należy o tym pamiętać i uwzględnić, ponieważ mamy juz 17 roczników takich osób.
    Warunek month<12 jest niespelniony.
    Pozdrawiam!

  8. Tak bay mieć spokój przynajmniej do 2090r.

    JS
    if ((intval(substr($pesel, 4, 2)) > 31)||(intval(substr($pesel, 2, 2)) > 32)||((intval(substr($pesel, 2, 2)) > 12) && (intval(substr($pesel, 2, 2)) 31)||(intval(substr($pesel, 2, 2)) > 32)||((intval(substr($pesel, 2, 2)) > 12) && (intval(substr($pesel, 2, 2)) < 20)))

  9. Jak widzę w kodzie programu, który jest interpretowany a nie kompilowany to się zawsze zastanawiam czy autor zaczynał swoją edukację programistyczną od VB-basicu.

    checksum = (1*parseInt(digits[0]) 3*parseInt(digits[1]) 7*parseInt(digits[2]) 9*parseInt(digits[3]) 1*parseInt(digits[4]) 3*parseInt(digits[5]) 7*parseInt(digits[6]) 9*parseInt(digits[7]) 1*parseInt(digits[8]) 3*parseInt(digits[9]));

    To można napisać dwa razy krócej gdy się obejrzy podręcznik javaskryptu. To samo dotyczy kodu w PHP.

  10. Formularz kontaktowy źle działa. Jak wpisałem kawałek kodu w javascript to mi wywalił takie ostrzeżenia:

    Warning: Creating default object from empty value in /home/virtmedia/domains/kaweczynski.pl/public_html/blog.aleksander/wp-content/plugins/ajax-comments/ajax-comments.php on line 203

    Warning: Cannot modify header information – headers already sent by (output started at /home/virtmedia/domains/kaweczynski.pl/public_html/blog.aleksander/wp-content/plugins/ajax-comments/ajax-comments.php:203) in /home/virtmedia/domains/kaweczynski.pl/public_html/blog.aleksander/wp-content/plugins/ajax-comments/ajax-comments.php on line 206

  11. ale dziurawy ten walidator.
    Przykładowo numer 96023112349 zwraca jako true, mimo iż pesel jest niepoprawny (w 95 roku nie było 29 dni w lutym).
    Ten warunek też powinien być sprawdzany i uwzględniany.

  12. PESEL po 2000 roku nie przejdzie walidacji ponieważ

    miesiąc = miesiąc 20
    czyli dla daty urodzenia 2019.07.01 to będzie 192701XXXXX

    dziwię się, że tego nie wiecie.
    Wzięło się to stąd że wciąż żyją ludzie który urodzili się na początku XX wieku a rok w PESELu ma tylko dwa znaki więc mogły by się dublować i nie wiadomo by było czy to starzec czy dziecko.
    Żeby nie zmieniać systemu, nie dodawać cyfr rząd poszedł prostą drogą i dodał 20 do miesiąca. Za sto lat można w ten sposób dodać kolejne 20 i wciąż system będzie działał a PESEL będzie unikalny. Takiej numeracji starczy na 500 lat.

  13. Pattern na NIP jest nieprawidłowy.
    Prawidłowym patternem dla polskich nipów jest: [1-9]((\d[1-9])|([1-9]\d))\d{7}

    Tj. na drugim i trzecim miejscu nie mogą być jednocześnie zera

Skomentuj Krzysztof Grabania Anuluj pisanie odpowiedzi

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.