liquid_feedback_frontend
diff app/main/registration/_check_fiscal_code.lua @ 1309:32cc544d5a5b
Cumulative patch for upcoming frontend version 4
author | bsw/jbe |
---|---|
date | Sun Jul 15 14:07:29 2018 +0200 (2018-07-15) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/app/main/registration/_check_fiscal_code.lua Sun Jul 15 14:07:29 2018 +0200 1.3 @@ -0,0 +1,198 @@ 1.4 +local oddmap = { 1.5 + [0] = 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 1.6 + 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 1.7 + 10, 22, 25, 24, 23 1.8 +} 1.9 + 1.10 +local monthtable = { 1.11 + "A", "B", "C", "D", "E", "H", "L", "M", "P", "R", "S", "T" 1.12 +} 1.13 + 1.14 +local function removeaccent(str) 1.15 + local gsub = string.gsub 1.16 + str = gsub(str, "\195\129", "A") 1.17 + str = gsub(str, "\195\128", "A") 1.18 + str = gsub(str, "\195\161", "a") 1.19 + str = gsub(str, "\195\160", "a") 1.20 + str = gsub(str, "\195\137", "E") 1.21 + str = gsub(str, "\195\136", "E") 1.22 + str = gsub(str, "\195\169", "e") 1.23 + str = gsub(str, "\195\168", "e") 1.24 + str = gsub(str, "\195\141", "I") 1.25 + str = gsub(str, "\195\140", "I") 1.26 + str = gsub(str, "\195\173", "i") 1.27 + str = gsub(str, "\195\172", "i") 1.28 + str = gsub(str, "\195\147", "O") 1.29 + str = gsub(str, "\195\146", "O") 1.30 + str = gsub(str, "\195\179", "o") 1.31 + str = gsub(str, "\195\178", "o") 1.32 + str = gsub(str, "\195\154", "U") 1.33 + str = gsub(str, "\195\153", "U") 1.34 + str = gsub(str, "\195\186", "u") 1.35 + str = gsub(str, "\195\185", "u") 1.36 + return str 1.37 +end 1.38 + 1.39 +local function normalize_name(str) 1.40 + local gsub = string.gsub 1.41 + str = removeaccent(str) 1.42 + str = gsub(str, " ", "") 1.43 + str = gsub(str, "-", "") 1.44 + str = gsub(str, "'", "") 1.45 + str = gsub(str, "\226\128\146", "") 1.46 + str = gsub(str, "\226\128\147", "") 1.47 + str = gsub(str, "\226\128\148", "") 1.48 + if string.find(str, "^[A-Za-z]+$") then 1.49 + return string.upper(str) 1.50 + else 1.51 + return nil 1.52 + end 1.53 +end 1.54 + 1.55 +local function remove_consonants(str) 1.56 + return (string.gsub(str, "[BCDFGHJKLMNPQRSTVWXYZ]", "")) 1.57 +end 1.58 + 1.59 +local function remove_vowels(str) 1.60 + return (string.gsub(str, "[AEIOU]", "")) 1.61 +end 1.62 + 1.63 +local function numberize(str) 1.64 + local gsub = string.gsub 1.65 + str = gsub(str, "L", "0") 1.66 + str = gsub(str, "M", "1") 1.67 + str = gsub(str, "N", "2") 1.68 + str = gsub(str, "P", "3") 1.69 + str = gsub(str, "Q", "4") 1.70 + str = gsub(str, "R", "5") 1.71 + str = gsub(str, "S", "6") 1.72 + str = gsub(str, "T", "7") 1.73 + str = gsub(str, "U", "8") 1.74 + str = gsub(str, "V", "9") 1.75 + return str 1.76 +end 1.77 + 1.78 +return function(code, data) 1.79 + local sub = string.sub 1.80 + local byte = string.byte 1.81 + local byte0 = byte("0") 1.82 + local byteA = byte("A") 1.83 + local function byteat(str, pos) 1.84 + return (byte(sub(str, pos, pos))) 1.85 + end 1.86 + if #code ~= 16 then 1.87 + return false, "Invalid length" 1.88 + end 1.89 + local sum = 0 1.90 + for i = 1, 15, 2 do 1.91 + local b = byteat(code, i) 1.92 + local b0 = b - byte0 1.93 + if b0 >= 0 and b0 <= 9 then 1.94 + sum = sum + oddmap[b0] 1.95 + else 1.96 + local bA = b - byteA 1.97 + if bA >= 0 and bA <= 25 then 1.98 + sum = sum + oddmap[bA] 1.99 + else 1.100 + return false, "Invalid character" 1.101 + end 1.102 + end 1.103 + end 1.104 + for i = 2, 14, 2 do 1.105 + local b = byteat(code, i) 1.106 + local b0 = b - byte0 1.107 + if b0 >= 0 and b0 <= 9 then 1.108 + sum = sum + b0 1.109 + else 1.110 + local bA = b - byteA 1.111 + if bA >= 0 and bA <= 25 then 1.112 + sum = sum + bA 1.113 + else 1.114 + return false, "Invalid character" 1.115 + end 1.116 + end 1.117 + end 1.118 + local check = byteat(code, 16) 1.119 + local checkA = check - byteA 1.120 + if checkA >= 0 and checkA <= 25 then 1.121 + if checkA ~= sum % 26 then 1.122 + return false, "Invalid checksum" 1.123 + end 1.124 + else 1.125 + local check0 = check - byte0 1.126 + if check0 >= 0 and check0 <= 9 then 1.127 + return false, "Checksum must not be numeric" 1.128 + else 1.129 + return false, "Invalid character" 1.130 + end 1.131 + end 1.132 + if data then 1.133 + if data.last_name then 1.134 + local name = normalize_name(data.last_name) 1.135 + if not name then 1.136 + return false, "Invalid last name" 1.137 + end 1.138 + local consonants = remove_vowels(name) 1.139 + local short = sub(consonants, 1, 3) 1.140 + if #short < 3 then 1.141 + local vowels = remove_consonants(name) 1.142 + short = short .. sub(vowels, 1, 3 - #short) 1.143 + while #short < 3 do 1.144 + short = short .. "X" 1.145 + end 1.146 + end 1.147 + if short ~= sub(code, 1, 3) then 1.148 + return false, "Last name not matching" 1.149 + end 1.150 + end 1.151 + if data.first_name then 1.152 + local name = normalize_name(data.first_name) 1.153 + if not name then 1.154 + return false, "Invalid first name" 1.155 + end 1.156 + local consonants = remove_vowels(name) 1.157 + local short 1.158 + if #consonants >= 4 then 1.159 + short = sub(consonants, 1, 1) .. sub(consonants, 3, 4) 1.160 + else 1.161 + short = consonants 1.162 + if #short < 3 then 1.163 + local vowels = remove_consonants(name) 1.164 + short = short .. sub(vowels, 1, 3 - #short) 1.165 + while #short < 3 do 1.166 + short = short .. "X" 1.167 + end 1.168 + end 1.169 + end 1.170 + if short ~= sub(code, 4, 6) then 1.171 + return false, "First name not matching" 1.172 + end 1.173 + end 1.174 + if data.year then 1.175 + local year = tostring(data.year % 100) 1.176 + if #year < 2 then 1.177 + year = "0" .. year 1.178 + end 1.179 + if year ~= numberize(sub(code, 7, 8)) then 1.180 + return false, "Year of birth not matching" 1.181 + end 1.182 + end 1.183 + if data.month then 1.184 + local monthchar = monthtable[data.month] 1.185 + if monthchar ~= sub(code, 9, 9) then 1.186 + return false, "Month of birth not matching" 1.187 + end 1.188 + end 1.189 + if data.day then 1.190 + local day = tostring(data.day) 1.191 + if #day < 2 then 1.192 + day = "0" .. day 1.193 + end 1.194 + local daycode = numberize(sub(code, 10, 11)) 1.195 + if day ~= daycode and tostring(day + 40) ~= daycode then 1.196 + return false, "Day of birth not matching" 1.197 + end 1.198 + end 1.199 + end 1.200 + return true 1.201 +end