Skatteverket publicerar en skrift SKV 704 (upplaga 8 är senaste i skrivande stund) som beskriver hur personnummret är uppbyggt. I avsnittet "Personnummer i ADB-system" står följande:
Personnummer i ADB-system
Inom Skatteverkets ADB-system för folkbokföring
lagras personnumret med tolv siffror, där de två in-
ledande siffrorna anger under vilket århundrade en
person är född. Siffran för århundrade kan vara 18, 19
eller – efter millennieskiftet – 20.Siffran visas normalt inte på terminalbilder eller
utskrifter men ingår i aviseringen av folkbokförings-
uppgifter till andra myndigheter via Navet, Skatte-
verkets system för distribution av folkbokföringsupp-
gifter till samhället.
SWAMID rekommenderar att man följer denna princip för personnummer som skickas via attributet norEduPersonNIN, dvs att personnummer representeras som 12 siffror utan bindestreck eller mellanslag.
Interimspersonnummer i Ladok och VHS antagningssystem
Ett interimspersonnummer i Ladok är konstruerat som ÅÅÅÅMMDDXnnn, d v s med en versal bokstav i den 9:e positionen samt en könsvariabel i den 11:e positionen. Bokstaven behandlas som en etta vid uträkning av kontrollsiffran i position 12. Traditionellt har s.k. P-nummer används lokalt i Ladok men efter införandet av VHS antagningssystem har s.k. T-nummer används nationellt.
När samtliga tillgängliga interimspersonnummer har tagit slut för en bokstav fortsätter man med nästa i nedanstående ordning:
- T
- R
- S
- U
- W
- X
- J
- K
- L
- M
- N
Efter 'T' ska 'R' användas till dess samtliga tillgängliga interimspersonnummer med den bokstaven är slut för det aktuella datumet. Därefter används 'S', osv.
Hur gör man om man har personnumret i 12 tecken men inte i LDAP-attributet norEduPersonNin?
Förutsättning:
- Attributet mittPersonnummer hämtas från källan myLDAP
<resolver:AttributeDefinition id="norEduPersonNIN" xsi:type="Simple" xmlns="urn:mace:shibboleth:2.0:resolver:ad" sourceAttributeID="mittPersonnummer"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="urn:mace:dir:attribute-def:norEduPersonNIN" /> <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="urn:oid:1.3.6.1.4.1.2428.90.1.5" friendlyName="norEduPersonNIN" /> </resolver:AttributeDefinition>
Hur gör man om man har personnumret i 10 tecken?
Förutsättning:
- Attributet mittPersonnummer hämtas från källan myLDAP
- Personnumret kan vara både 10 och 12 siffror
- Använder "sliding windows" utan offset för att dynamiskt hantera 2000-problemet
<resolver:AttributeDefinition id="norEduPersonNIN" xsi:type="Script" xmlns="urn:mace:shibboleth:2.0:resolver:ad" sourceAttributeID="mittPersonnummer"> <resolver:Dependency ref="myLDAP" /> <resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="urn:mace:dir:attribute-def:norEduPersonNIN" /> <resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder" name="urn:oid:1.3.6.1.4.1.2428.90.1.5" friendlyName="norEduPersonNIN" /> <Script> <![CDATA[ // import needed packages importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider); // Setup a logger importPackage(Packages.org.slf4j); logger = LoggerFactory.getLogger("se.su.it.shibboleth.idp.ninDecorator"); // the attribute which is to be populated norEduPersonNIN = new BasicAttribute("norEduPersonNIN"); // Get a ref to the SSN received from ldap ssn=mittPersonnummer.getValues().get(0); logger.debug("Doing decoration of ssn " + ssn); // Only do decoration of SSNs which are on the format YYMMDDxxxx if(ssn.length() == 10) { // Create the two alternative return strings we have to choose between pnr19 = "19" + ssn; pnr20 = "20" + ssn; // Extract year/month/day from the SSN string m_y = ssn.substring(0,2); m_m = ssn.substring(2,4); m_d = ssn.substring(4,6); // Create a Date object for the 20xx case datePnr = new Date("20" + m_y, m_m-1, m_d); // Create a Date object for the current date dateCur = new Date(); // Some debug logging logger.debug("pnr19: " + pnr19); logger.debug("pnr20: " + pnr20); logger.debug("datePnr: " + datePnr); logger.debug("dateCur: " + dateCur); // If the 20xx case is in the future we assume 19xx for the NIN attribute if(datePnr>dateCur) { logger.info("Returning 19xx pnr since the 20xx case is in the future"); norEduPersonNIN.getValues().add(pnr19); } else { logger.info("Returning 20xx pnr since it is more present than the 19xx one."); norEduPersonNIN.getValues().add(pnr20); } } else if(ssn.length() == 12) { logger.info("Returning pnr as-is since it contains 12 chars"); norEduPersonNIN.getValues().add(ssn); } else { logger.error("Not setting any norEduPersonNIN since it is bogus (length=" + ssn.length() + "): " + ssn); } ]]> </Script> </resolver:AttributeDefinition>