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