anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

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 }