validation_BE_NRN.c (2298B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2026 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file reducer/validation_BE_NRN.c 18 * @brief Validation for Belgian national register numbers 19 * @author Christian Grothoff 20 */ 21 #include <string.h> 22 #include <stdbool.h> 23 #include <stdlib.h> 24 25 26 /** 27 * Function to validate a Belgian national register number (rijksregisternummer 28 * / numéro de registre national). 29 * 30 * The number is YYMMDD (date of birth) + SSS (serial) + CC (check). The check 31 * is 97 minus the first nine digits taken as a number, modulo 97. The century 32 * is not encoded, so for people born from 2000 on a '2' is prepended to the 33 * nine digits before the computation. Since we cannot tell the two cases 34 * apart from the number alone, either variant matching is accepted. 35 * 36 * See https://nl.wikipedia.org/wiki/Rijksregisternummer 37 * 38 * @param nrn_number national register number to validate (input) 39 * @return true if validation passed, else false 40 */ 41 bool 42 BE_NRN_check (const char *nrn_number); 43 44 /* declaration to fix compiler warning */ 45 bool 46 BE_NRN_check (const char *nrn_number) 47 { 48 unsigned long long base = 0; 49 unsigned int check = 0; 50 51 if (strlen (nrn_number) != 11) 52 return false; 53 for (unsigned int i = 0; i<11; i++) 54 { 55 unsigned char c = (unsigned char) nrn_number[i]; 56 57 if ( ('0' > c) || ('9' < c) ) 58 return false; 59 if (i < 9) 60 base = base * 10 + (c - '0'); 61 else 62 check = check * 10 + (c - '0'); 63 } 64 /* born before 2000: the nine digits are used as they are */ 65 if (check == 97 - (base % 97)) 66 return true; 67 /* born from 2000 on: a '2' is prepended */ 68 return (check == 97 - ((2000000000ULL + base) % 97)); 69 }