Created
November 5, 2013 08:25
-
-
Save nifo/7315616 to your computer and use it in GitHub Desktop.
How to validate a swedish, so called, personnummer. In other countries it might be called social security number.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def valid_pnummer(pnr): | |
"""Returns True if input is a valid personnummer. | |
Can be with or without "-" and 19~ | |
Requirement from the swedish tax agency (2013-08-05): | |
http://www.skatteverket.se/privat/folkbokforing/omfolkbokforing/personnumretsuppbyggnad.4.18e1b10334ebe8bc80001502.html | |
Kontrollsiffran | |
Fjärde siffran i födelsenumret är en kontrollsiffra. Den räknas ut | |
maskinellt med ledning av födelsetiden och födelsenumret. | |
Här följer ett exempel på hur man kan räkna fram kontrollsiffran | |
(enligt den s.k. modulus-10-metoden med vikterna 1 och 2): | |
1. Siffrorna i födelsetiden och födelsenumret multipliceras växelvismed 2 | |
och 1. | |
6 4 0 8 2 3 – 3 2 3 | |
2 1 2 1 2 1 2 1 2 | |
12,4,0,8,4,3, 6,2,6 | |
2. Lägg ihop siffrorna i produkterna. Obs! 12 räknas som 1+2 | |
1+2+4+0+8+4+3+6+2+6=36 | |
3. Entalssiffran (6) i siffersumman dras från talet 10. 10-6=4. | |
Restsiffran (4) blir kontrollsiffra vilket gör att personnumret i | |
exemplet blir 640823-3234. Är restsiffran 10, blir kontrollsiffran 0. | |
Test cases: | |
assert valid_pnummer('196408233234') | |
assert valid_pnummer('19880529-7838') | |
assert valid_pnummer('198805297838') | |
assert valid_pnummer('880529-7838') | |
assert valid_pnummer('8805297838') | |
assert valid_pnummer('190202-9246') | |
assert valid_pnummer('19190202-9246') | |
assert valid_pnummer('1902029246') | |
assert valid_pnummer('1902029246') | |
""" | |
# Conditions | |
pnr = str(pnr) | |
if not all(c in '0123456879-' for c in pnr): return False | |
if '-' in pnr: pnr = pnr.replace('-','') | |
if len(pnr) == 12: pnr = pnr[2:] | |
if not len(pnr) == 10: return False | |
# pnr is now definitely a string in format ÅÅMMDDNNNN | |
# The three steps as described in the specification | |
double_even = ''.join((str(int(c) * 2) for c in pnr[::2])) | |
pnr_sum = (sum(int(n) for n in double_even + pnr[1::2])) | |
return pnr_sum % 10 == 0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment