Skip to content

Instantly share code, notes, and snippets.

@jonelf
Created November 4, 2021 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonelf/fc2657d5a77164075d4a50661648fab8 to your computer and use it in GitHub Desktop.
Save jonelf/fc2657d5a77164075d4a50661648fab8 to your computer and use it in GitHub Desktop.
Validates a Swedish personal identity number.
package com.example;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.regex.*;
public class Main {
final static String DATE_FORMAT = "yyMMdd";
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Enter one argument as a personnummer.");
System.exit(1);
}
String personnummer = args[0];
if (!checkFormat(personnummer)) {
System.err.println("Incorrect format.");
System.exit(2);
}
personnummer = transformTo10Digits(personnummer);
Boolean validDate = validateDate(personnummer.substring(0,6));
Boolean samordningsnummer = isSamordningsnummer(personnummer);
if (!validDate && !samordningsnummer){
System.out.println(personnummer + " has an invalid date.");
System.exit(3);
}
Boolean valid = validateLuhnChecksum(personnummer);
System.out.println(personnummer + " is " + (valid ? "valid" : "invalid") + (samordningsnummer ? " and is a samordningsnummer" : "") + ".");
System.exit(valid ? 0 : 3);
}
private static Boolean isSamordningsnummer(String personnummer) {
System.out.println("samord" + personnummer.substring(4,6));
Boolean isSamordningsnummer = false;
int day = Integer.parseInt(personnummer.substring(4,6));
if (day > 60 && day < 92) {
isSamordningsnummer = true;
}
return isSamordningsnummer;
}
private static Boolean validateLuhnChecksum(String personnummer) {
int checksum = 0;
String[] pnarr = personnummer.split("");
for (int i = 0; i < personnummer.length(); i++) {
int n = Integer.parseInt(pnarr[i]);
if (i % 2 == 0) {
n *= 2;
if (n > 9) {
n = (n % 10) + 1;
}
}
checksum += n;
}
return checksum % 10 == 0;
}
private static String transformTo10Digits(String personnummer) {
// Remove - or +.
personnummer = personnummer.replaceAll("[-\\+]", "");
// Strip century if included.
if (personnummer.length() == 12) {
personnummer = personnummer.substring(2);
}
return personnummer;
}
private static boolean checkFormat(String personnummer) {
// Checks that the personnummer is 10 or 12 digits
// with optional - or + before the last 4.
Pattern p = Pattern.compile("^\\d{6}(?:\\d{2})?[-\\s\\+]?\\d{4}$");
Matcher m = p.matcher(personnummer);
return m.matches();
}
public static boolean validateDate(String date)
{
try {
DateFormat df = new SimpleDateFormat(DATE_FORMAT);
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
}
@jonaselfstrom
Copy link

Run as
java personnummer com.example.Main 190910799824

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment