Skip to content

Instantly share code, notes, and snippets.

@nifo
Created November 5, 2013 08:25
Show Gist options
  • Save nifo/7315616 to your computer and use it in GitHub Desktop.
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.
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