validation_DE_SVN.c (2558B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020, 2021 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_DE_SVN.c 18 * @brief 19 * @author Christian Grothoff 20 * @author Dominik Meister 21 * @author Dennis Neufeld 22 */ 23 #include <string.h> 24 #include <stdbool.h> 25 26 /** 27 * Sum up all digits in @a v and return the result. 28 */ 29 static unsigned int 30 q (unsigned int v) 31 { 32 unsigned int r = 0; 33 34 while (0 != v) 35 { 36 r += v % 10; 37 v = v / 10; 38 } 39 return r; 40 } 41 42 43 /** 44 * Function to validate a German Social Security number. 45 * 46 * See https://www.financescout24.de/wissen/ratgeber/sozialversicherungsnummer 47 * and https://de.wikipedia.org/wiki/Versicherungsnummer 48 * for the structure! 49 * 50 * @param ssn_number social security number to validate (input) 51 * @return true if validation passed, else false 52 */ 53 bool 54 DE_SVN_check (const char *ssn_number); 55 56 /* declaration to fix compiler warning */ 57 bool 58 DE_SVN_check (const char *ssn_number) 59 { 60 static const unsigned int factors[] = { 61 2, 1, 2, 5, 7, 1, 2, 1, 2, 1, 2, 1 62 }; 63 unsigned int sum = 0; 64 65 if (strlen (ssn_number) != 12) 66 return false; 67 for (unsigned int i = 0; i<8; i++) 68 { 69 unsigned char c = (unsigned char) ssn_number[i]; 70 71 if ( ('0' > c) || ('9' < c) ) 72 return false; 73 sum += q ((c - '0') * factors[i]); 74 } 75 { 76 unsigned char c = (unsigned char) ssn_number[8]; 77 unsigned int v = (c - 'A' + 1); 78 79 if ( ('A' > c) || ('Z' < c) ) 80 return false; 81 sum += q ((v / 10) * factors[8]); 82 sum += q ((v % 10) * factors[9]); 83 } 84 for (unsigned int i = 9; i<11; i++) 85 { 86 unsigned char c = ssn_number[i]; 87 88 if ( ('0' > c) || ('9' < c) ) 89 return false; 90 sum += q ((c - '0') * factors[i + 1]); 91 } 92 if (ssn_number[11] != '0' + (sum % 10)) 93 return false; 94 { 95 unsigned int month = (ssn_number[4] - '0') * 10 + (ssn_number[5] - '0'); 96 97 if ( (0 == month) || 98 (12 < month) ) 99 return false; 100 } 101 return true; 102 }