liquid_feedback_frontend
view app/main/registration/_check_fiscal_code.lua @ 1642:45287f1037fb
Support precondtions if LDAP accounts may login
| author | bsw | 
|---|---|
| date | Tue Feb 09 21:07:16 2021 +0100 (2021-02-09) | 
| parents | 32cc544d5a5b | 
| children | 
 line source
     1 local oddmap = {
     2   [0] = 1, 0, 5, 7, 9, 13, 15, 17, 19, 21,
     3   2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16,
     4   10, 22, 25, 24, 23
     5 }
     7 local monthtable = {
     8   "A", "B", "C", "D", "E", "H", "L", "M", "P", "R", "S", "T"
     9 }
    11 local function removeaccent(str)
    12   local gsub = string.gsub
    13   str = gsub(str, "\195\129", "A")
    14   str = gsub(str, "\195\128", "A")
    15   str = gsub(str, "\195\161", "a")
    16   str = gsub(str, "\195\160", "a")
    17   str = gsub(str, "\195\137", "E")
    18   str = gsub(str, "\195\136", "E")
    19   str = gsub(str, "\195\169", "e")
    20   str = gsub(str, "\195\168", "e")
    21   str = gsub(str, "\195\141", "I")
    22   str = gsub(str, "\195\140", "I")
    23   str = gsub(str, "\195\173", "i")
    24   str = gsub(str, "\195\172", "i")
    25   str = gsub(str, "\195\147", "O")
    26   str = gsub(str, "\195\146", "O")
    27   str = gsub(str, "\195\179", "o")
    28   str = gsub(str, "\195\178", "o")
    29   str = gsub(str, "\195\154", "U")
    30   str = gsub(str, "\195\153", "U")
    31   str = gsub(str, "\195\186", "u")
    32   str = gsub(str, "\195\185", "u")
    33   return str
    34 end
    36 local function normalize_name(str)
    37   local gsub = string.gsub
    38   str = removeaccent(str)
    39   str = gsub(str, " ", "")
    40   str = gsub(str, "-", "")
    41   str = gsub(str, "'", "")
    42   str = gsub(str, "\226\128\146", "")
    43   str = gsub(str, "\226\128\147", "")
    44   str = gsub(str, "\226\128\148", "")
    45   if string.find(str, "^[A-Za-z]+$") then
    46     return string.upper(str)
    47   else
    48     return nil
    49   end
    50 end
    52 local function remove_consonants(str)
    53   return (string.gsub(str, "[BCDFGHJKLMNPQRSTVWXYZ]", ""))
    54 end
    56 local function remove_vowels(str)
    57   return (string.gsub(str, "[AEIOU]", ""))
    58 end
    60 local function numberize(str)
    61   local gsub = string.gsub
    62   str = gsub(str, "L", "0")
    63   str = gsub(str, "M", "1")
    64   str = gsub(str, "N", "2")
    65   str = gsub(str, "P", "3")
    66   str = gsub(str, "Q", "4")
    67   str = gsub(str, "R", "5")
    68   str = gsub(str, "S", "6")
    69   str = gsub(str, "T", "7")
    70   str = gsub(str, "U", "8")
    71   str = gsub(str, "V", "9")
    72   return str
    73 end
    75 return function(code, data)
    76   local sub = string.sub
    77   local byte = string.byte
    78   local byte0 = byte("0")
    79   local byteA = byte("A")
    80   local function byteat(str, pos)
    81     return (byte(sub(str, pos, pos)))
    82   end
    83   if #code ~= 16 then
    84     return false, "Invalid length"
    85   end
    86   local sum = 0
    87   for i = 1, 15, 2 do
    88     local b = byteat(code, i)
    89     local b0 = b - byte0
    90     if b0 >= 0 and b0 <= 9 then
    91       sum = sum + oddmap[b0]
    92     else
    93       local bA = b - byteA
    94       if bA >= 0 and bA <= 25 then
    95         sum = sum + oddmap[bA]
    96       else
    97         return false, "Invalid character"
    98       end
    99     end
   100   end
   101   for i = 2, 14, 2 do
   102     local b = byteat(code, i)
   103     local b0 = b - byte0
   104     if b0 >= 0 and b0 <= 9 then
   105       sum = sum + b0
   106     else
   107       local bA = b - byteA
   108       if bA >= 0 and bA <= 25 then
   109         sum = sum + bA
   110       else
   111         return false, "Invalid character"
   112       end
   113     end
   114   end
   115   local check = byteat(code, 16)
   116   local checkA = check - byteA
   117   if checkA >= 0 and checkA <= 25 then
   118     if checkA ~= sum % 26 then
   119       return false, "Invalid checksum"
   120     end
   121   else
   122     local check0 = check - byte0
   123     if check0 >= 0 and check0 <= 9 then
   124       return false, "Checksum must not be numeric"
   125     else
   126       return false, "Invalid character"
   127     end
   128   end
   129   if data then
   130     if data.last_name then
   131       local name = normalize_name(data.last_name)
   132       if not name then
   133         return false, "Invalid last name"
   134       end
   135       local consonants = remove_vowels(name)
   136       local short = sub(consonants, 1, 3)
   137       if #short < 3 then
   138         local vowels = remove_consonants(name)
   139         short = short .. sub(vowels, 1, 3 - #short)
   140         while #short < 3 do
   141           short = short .. "X"
   142         end
   143       end
   144       if short ~= sub(code, 1, 3) then
   145         return false, "Last name not matching"
   146       end
   147     end
   148     if data.first_name then
   149       local name = normalize_name(data.first_name)
   150       if not name then
   151         return false, "Invalid first name"
   152       end
   153       local consonants = remove_vowels(name)
   154       local short
   155       if #consonants >= 4 then
   156         short = sub(consonants, 1, 1) .. sub(consonants, 3, 4)
   157       else
   158         short = consonants
   159         if #short < 3 then
   160           local vowels = remove_consonants(name)
   161           short = short .. sub(vowels, 1, 3 - #short)
   162           while #short < 3 do
   163             short = short .. "X"
   164           end
   165         end
   166       end
   167       if short ~= sub(code, 4, 6) then
   168         return false, "First name not matching"
   169       end
   170     end
   171     if data.year then
   172       local year = tostring(data.year % 100)
   173       if #year < 2 then
   174         year = "0" .. year
   175       end
   176       if year ~= numberize(sub(code, 7, 8)) then
   177         return false, "Year of birth not matching"
   178       end
   179     end
   180     if data.month then
   181       local monthchar = monthtable[data.month]
   182       if monthchar ~= sub(code, 9, 9) then
   183         return false, "Month of birth not matching"
   184       end
   185     end
   186     if data.day then
   187       local day = tostring(data.day)
   188       if #day < 2 then
   189         day = "0" .. day
   190       end
   191       local daycode = numberize(sub(code, 10, 11))
   192       if day ~= daycode and tostring(day + 40) ~= daycode then
   193         return false, "Day of birth not matching"
   194       end
   195     end
   196   end
   197   return true
   198 end
