validation_IT_CF.c (3893B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 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_IT_CF.c 18 * @brief validation of Italian Code Fiscales 19 * @author Christian Grothoff 20 */ 21 #include <string.h> 22 #include <stdbool.h> 23 #include <stdio.h> 24 #include <math.h> 25 26 struct MapEntry 27 { 28 char in; 29 unsigned int out; 30 }; 31 32 33 static const struct MapEntry odd[] = { 34 { '0', 1}, 35 { '9', 21}, 36 { 'I', 19 }, 37 { 'R', 8}, 38 { '1', 0}, 39 { 'A', 1}, 40 { 'J', 21}, 41 { 'S', 12}, 42 {'2', 5}, 43 {'B', 0}, 44 {'K', 2}, 45 {'T', 14}, 46 {'3', 7}, 47 {'C', 5}, 48 {'L', 4}, 49 {'U', 16}, 50 {'4', 9}, 51 {'D', 7}, 52 {'M', 18}, 53 {'V', 10}, 54 {'5', 13}, 55 {'E', 9}, 56 {'N', 20}, 57 {'W', 22}, 58 {'6', 15}, 59 {'F', 13}, 60 {'O', 11}, 61 {'X', 25}, 62 {'7', 17}, 63 {'G', 15}, 64 {'P', 3}, 65 {'Y', 24}, 66 {'8', 19}, 67 {'H', 17}, 68 {'Q', 6}, 69 {'Z', 23}, 70 {'\0', 0} 71 }; 72 73 74 static const struct MapEntry even[] = { 75 { '0', 0}, 76 { '1', 1}, 77 { '2', 2 }, 78 { '3', 3}, 79 { '4', 4}, 80 { '5', 5}, 81 { '6', 6 }, 82 { '7', 7 }, 83 {'8', 8}, 84 {'9', 9}, 85 {'A', 0}, 86 {'B', 1}, 87 {'C', 2}, 88 {'D', 3}, 89 {'E', 4}, 90 {'F', 5}, 91 {'G', 6}, 92 {'H', 7}, 93 {'I', 8}, 94 {'J', 9}, 95 {'K', 10}, 96 {'L', 11}, 97 {'M', 12}, 98 {'N', 13}, 99 {'O', 14}, 100 {'P', 15}, 101 {'Q', 16}, 102 {'R', 17}, 103 {'S', 18}, 104 {'T', 19}, 105 {'U', 20}, 106 {'V', 21}, 107 {'W', 22}, 108 {'X', 23}, 109 {'Y', 24}, 110 {'Z', 25}, 111 {'\0', 0} 112 }; 113 114 115 static const struct MapEntry rem[] = { 116 {'A', 0}, 117 {'B', 1}, 118 {'C', 2}, 119 {'D', 3}, 120 {'E', 4}, 121 {'F', 5}, 122 {'G', 6}, 123 {'H', 7}, 124 {'I', 8}, 125 {'J', 9}, 126 {'K', 10}, 127 {'L', 11}, 128 {'M', 12}, 129 {'N', 13}, 130 {'O', 14}, 131 {'P', 15}, 132 {'Q', 16}, 133 {'R', 17}, 134 {'S', 18}, 135 {'T', 19}, 136 {'U', 20}, 137 {'V', 21}, 138 {'W', 22}, 139 {'X', 23}, 140 {'Y', 24}, 141 {'Z', 25}, 142 {'\0', 0} 143 }; 144 145 146 /** 147 * Lookup @a in in @a map. Set @a fail to true if @a in is not found. 148 * 149 * @param map character map to search 150 * @param in character to search for 151 * @param[out] fail set to true on error 152 * @return map value, 0 on error 153 */ 154 static unsigned int 155 lookup (const struct MapEntry *map, 156 char in, 157 bool *fail) 158 { 159 for (unsigned int i = 0; '\0' != map[i].in; i++) 160 if (in == map[i].in) 161 return map[i].out; 162 *fail = true; 163 return 0; 164 } 165 166 167 /** 168 * Function to validate an italian code fiscale number. 169 * See https://en.wikipedia.org/wiki/Italian_fiscal_code 170 * 171 * @param cf_number square number to validate (input) 172 * @return true if @a cf_number is a valid, else false 173 */ 174 bool 175 IT_CF_check (const char *cf_number); 176 177 /* declaration to fix compiler warning */ 178 bool 179 IT_CF_check (const char *cf_number) 180 { 181 unsigned int sum = 0; 182 bool fail = false; 183 184 if (strlen (cf_number) != 16) 185 return false; 186 for (unsigned int i = 0; i<15; i += 2) 187 sum += lookup (odd, 188 cf_number[i], 189 &fail); 190 for (unsigned int i = 1; i<15; i += 2) 191 sum += lookup (even, 192 cf_number[i], 193 &fail); 194 sum %= 26; 195 if (sum != lookup (rem, 196 cf_number[15], 197 &fail)) 198 return false; 199 if (fail) 200 return false; 201 return true; 202 }