I was wrong.
Semi-official and unofficial open source code is often hilariously bad, although the format is quite well documented in Wikipedia.
One thing that people seem to misunderstand is that it tries to disambiguate between two possible birth dates spaced by 100 years. That is, the national number of someone who was born on April, 16 1925 will be 25.04.16-123-47 and for someone who was born on April, 16 2025 that would be 25.04.16-123-76.
Here it goes in Java:
public class NationalNumber { private final String it; @Override public String toString() { return it; } public NationalNumber(String it) { it = it.replaceAll("[^\\d]", ""); if (it.length() != 11) { throw new RuntimeException("Bad format for it " + it); } long older = Long.parseLong(it.substring(0, 9)); long newer = Long.parseLong("2" + it.substring(0, 9)); long checksum = Long.parseLong(it.substring(9, 11)); if ((97L - older % 97L != checksum) && (97L - newer % 97L != checksum)) { throw new RuntimeException("Failed checksum for it " + it); } this.it = it; } }
For those interested in the nitty-gritty details, there are the French and Dutch documents describing the National Register system and a much more readable Reddit thread on the topic.