curp_generator 1.0.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a65ed003039b6871fef8ca8eca44a529706baf765010619457d8955d58ad032
4
- data.tar.gz: 184facb4300807434ad265dd068b1924e2ad884c29333839564efa2e79be8d9c
3
+ metadata.gz: 3b5959e0a3411b694ffc1dcf5f1bbdb70c61fd36bc1c9b5d9af34432258cd780
4
+ data.tar.gz: bb0746852c5bdcc5b68f9c707408d97b117acdae4bf020fadb3803d1a03bd31b
5
5
  SHA512:
6
- metadata.gz: a3d031d50701c6554cdc9f7c024e472157c27d58d1d8c42f4ccc60399b3a4b4b824ef144a26ebf9fa56eca25c4aae41d2120d98b0b5e8fd26fe6a93dcc8a3283
7
- data.tar.gz: c6647a39d66e0445feb5f1e0ccaf8508387f075916ce560750490e986d412976e5a3367bf821a9ac8103e65f0fbb611dbde2a9bccd63b7a1b37390b08ee48e75
6
+ metadata.gz: a4205e8fa460bbf8a13a50c5ebefa09e94a8ca2fa5919481d2e1897bb41d479a212a8b82f576fbfae37f1d8b15b6a317e36ccfbeb9d36241089e1882f0a86f30
7
+ data.tar.gz: 581a8781955d9385a3df50f7d45bc4c8fe53f8fafc29e6b1e1d483d458b9081ebbcef4fe836a12870c39cc797e2c739769a1c5bfca5476146bb4959b3ece209d
@@ -0,0 +1,55 @@
1
+ require 'curp_generator/catalogs'
2
+
3
+ class CurpGenerator::Base
4
+ include ::CurpGenerator::Catalogs
5
+
6
+ InvalidCurpArgumentError = Class.new(StandardError)
7
+
8
+ def generate
9
+ raise NotImplementedError
10
+ end
11
+
12
+ private
13
+
14
+ def valid_params?
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def error_message!
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def parse_attribute(attribute)
23
+ return if blank_string?(attribute)
24
+
25
+ str = remove_special_chars(attribute)
26
+ remove_composed_names(str)
27
+ end
28
+
29
+ def blank_string?(value)
30
+ value.to_s.strip.empty?
31
+ end
32
+
33
+ def remove_special_chars(string)
34
+ normalized = normalize(string)
35
+ normalized&.gsub(/[.'\d-]/, "")
36
+ end
37
+
38
+ def normalize(string)
39
+ string&.tr(
40
+ "ÀàÁáÄäÈèÉéËëÌìÍíÏïÒòÓóÖöÙùÚúÜüÑñ",
41
+ "AaAaAaEeEeEeIiIiIiOoOoOoUuUuUuXx"
42
+ )
43
+ end
44
+
45
+ def remove_composed_names(name)
46
+ name = name.upcase
47
+
48
+ COMPOSED_NAMES.each do |composed|
49
+ next unless name.include?(composed)
50
+
51
+ name = name.gsub(composed, '')
52
+ end
53
+ name
54
+ end
55
+ end
@@ -0,0 +1,44 @@
1
+ require 'curp_generator/base'
2
+
3
+ class CurpGenerator::BirthDate < ::CurpGenerator::Base
4
+ def initialize(birth_date)
5
+ @birth_date = birth_date
6
+ end
7
+
8
+ def self.generate(birth_date)
9
+ new(birth_date).generate
10
+ end
11
+
12
+ def self.homoclave_digit(birth_date)
13
+ new(birth_date).homoclave_digit
14
+ end
15
+
16
+ def generate
17
+ validate_params
18
+ parsed_date
19
+ end
20
+
21
+ def homoclave_digit
22
+ validate_params
23
+ @birth_date.year < 2000 ? '0' : 'A'
24
+ end
25
+
26
+ private
27
+
28
+ def validate_params
29
+ missing_birth_date_error! if blank_string?(@birth_date)
30
+ invalid_format_error! unless @birth_date.respond_to?(:strftime)
31
+ end
32
+
33
+ def missing_birth_date_error!
34
+ raise InvalidCurpArgumentError, 'Missing birth date'
35
+ end
36
+
37
+ def invalid_format_error!
38
+ raise InvalidCurpArgumentError, 'Invalid date format'
39
+ end
40
+
41
+ def parsed_date
42
+ @birth_date.strftime("%y%m%d")
43
+ end
44
+ end
@@ -0,0 +1,224 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+ module CurpGenerator
3
+ module Catalogs
4
+ STATES = {
5
+ 'AGUASCALIENTES' => 'AS',
6
+ 'AG' => 'AS',
7
+ 'AGU' => 'AS',
8
+ 'BAJA CALIFORNIA NORTE' => 'BC',
9
+ 'BC' => 'BC',
10
+ 'BCN' => 'BC',
11
+ 'BAJA CALIFORNIA SUR' => 'BS',
12
+ 'BS' => 'BS',
13
+ 'BCS' => 'BS',
14
+ 'CAMPECHE' => 'CC',
15
+ 'CM' => 'CC',
16
+ 'CAM' => 'CC',
17
+ 'CHIAPAS' => 'CS',
18
+ 'CS' => 'CS',
19
+ 'CHP' => 'CS',
20
+ 'CHIHUAHUA' => 'CH',
21
+ 'CH' => 'CH',
22
+ 'CHH' => 'CH',
23
+ 'COAHUILA' => 'CL',
24
+ 'CO' => 'CL',
25
+ 'COA' => 'CL',
26
+ 'COLIMA' => 'CM',
27
+ 'CL' => 'CM',
28
+ 'COL' => 'CM',
29
+ 'CIUDAD DE MEXICO' => 'DF',
30
+ 'DF' => 'DF',
31
+ 'CMX' => 'DF',
32
+ 'CDMX' => 'DF',
33
+ 'DURANGO' => 'DG',
34
+ 'DG' => 'DG',
35
+ 'DUR' => 'DG',
36
+ 'GUANAJUATO' => 'GT',
37
+ 'GT' => 'GT',
38
+ 'GUA' => 'GT',
39
+ 'GUERRERO' => 'GR',
40
+ 'GR' => 'GR',
41
+ 'GRO' => 'GR',
42
+ 'HIDALGO' => 'HG',
43
+ 'HG' => 'HG',
44
+ 'HID' => 'HG',
45
+ 'JALISCO' => 'JC',
46
+ 'JA' => 'JC',
47
+ 'JAL' => 'JC',
48
+ 'MEXICO' => 'MC',
49
+ 'EM' => 'MC',
50
+ 'MEX' => 'MC',
51
+ 'ESTADO DE MEXICO' => 'MC',
52
+ 'MICHOACAN' => 'MN',
53
+ 'MI' => 'MN',
54
+ 'MIC' => 'MN',
55
+ 'MORELOS' => 'MS',
56
+ 'MO' => 'MS',
57
+ 'MOR' => 'MS',
58
+ 'NAYARIT' => 'NT',
59
+ 'NA' => 'NT',
60
+ 'NAY' => 'NT',
61
+ 'NUEVO LEON' => 'NL',
62
+ 'NL' => 'NL',
63
+ 'NLE' => 'NL',
64
+ 'OAXACA' => 'OC',
65
+ 'OA' => 'OC',
66
+ 'OAX' => 'OC',
67
+ 'PUEBLA' => 'PL',
68
+ 'PU' => 'PL',
69
+ 'PUE' => 'PL',
70
+ 'QUERETARO' => 'QT',
71
+ 'QT' => 'QT',
72
+ 'QUE' => 'QT',
73
+ 'QUINTANA ROO' => 'QR',
74
+ 'QR' => 'QR',
75
+ 'ROO' => 'QR',
76
+ 'SAN LUIS POTOSI' => 'SP',
77
+ 'SL' => 'SP',
78
+ 'SLP' => 'SP',
79
+ 'SINALOA' => 'SL',
80
+ 'SI' => 'SL',
81
+ 'SIN' => 'SL',
82
+ 'SONORA' => 'SR',
83
+ 'SO' => 'SR',
84
+ 'SON' => 'SR',
85
+ 'TABASCO' => 'TC',
86
+ 'TB' => 'TC',
87
+ 'TAB' => 'TC',
88
+ 'TAMAULIPAS' => 'TS',
89
+ 'TM' => 'TS',
90
+ 'TAM' => 'TS',
91
+ 'TLAXCALA' => 'TL',
92
+ 'TL' => 'TL',
93
+ 'TLA' => 'TL',
94
+ 'VERACRUZ' => 'VZ',
95
+ 'VE' => 'VZ',
96
+ 'VER' => 'VZ',
97
+ 'YUCATAN' => 'YN',
98
+ 'YU' => 'YN',
99
+ 'YUC' => 'YN',
100
+ 'ZACATECAS' => 'ZS',
101
+ 'ZA' => 'ZS',
102
+ 'ZAC' => 'ZS'
103
+ }.freeze
104
+
105
+ FORBIDDEN_WORDS = {
106
+ 'BACA' => 'BXCA',
107
+ 'LOCO' => 'LXCO',
108
+ 'BAKA' => 'BXKA',
109
+ 'BUEI' => 'BXEI',
110
+ 'BUEY' => 'BXEY',
111
+ 'CACA' => 'CXCA',
112
+ 'CACO' => 'CXCO',
113
+ 'CAGA' => 'CXGA',
114
+ 'CAGO' => 'CXGO',
115
+ 'CAKA' => 'CXKA',
116
+ 'CAKO' => 'CXKO',
117
+ 'COGE' => 'CXGE',
118
+ 'COGI' => 'CXGI',
119
+ 'COJA' => 'CXJA',
120
+ 'COJE' => 'CXJE',
121
+ 'COJI' => 'CXJI',
122
+ 'COJO' => 'CXJO',
123
+ 'COLA' => 'CXLA',
124
+ 'CULO' => 'CXLO',
125
+ 'FALO' => 'FXLO',
126
+ 'FETO' => 'FXTO',
127
+ 'GETA' => 'GXTA',
128
+ 'GUEI' => 'GXEI',
129
+ 'GUEY' => 'GXEY',
130
+ 'JETA' => 'JXTA',
131
+ 'JOTO' => 'JXTO',
132
+ 'KACA' => 'KXCA',
133
+ 'KACO' => 'KXCO',
134
+ 'KAGA' => 'KXGA',
135
+ 'KAGO' => 'KXGO',
136
+ 'KAKA' => 'KXKA',
137
+ 'KAKO' => 'KXKO',
138
+ 'KOGE' => 'KXGE',
139
+ 'KOGI' => 'KXGI',
140
+ 'KOJA' => 'KXJA',
141
+ 'KOJE' => 'KXJE',
142
+ 'KOJI' => 'KXJI',
143
+ 'KOJO' => 'KXJO',
144
+ 'KOLA' => 'KXLA',
145
+ 'KULO' => 'KXLO',
146
+ 'LILO' => 'LXLO',
147
+ 'LOKA' => 'LXKA',
148
+ 'LOKO' => 'LXKO',
149
+ 'MAME' => 'MXME',
150
+ 'MAMO' => 'MXMO',
151
+ 'MEAR' => 'MXAR',
152
+ 'MEAS' => 'MXAS',
153
+ 'MEON' => 'MXON',
154
+ 'MIAR' => 'MXAR',
155
+ 'MION' => 'MXON',
156
+ 'MOCO' => 'MXCO',
157
+ 'MOKO' => 'MXKO',
158
+ 'MULA' => 'MXLA',
159
+ 'MULO' => 'MXLO',
160
+ 'NACA' => 'NXCA',
161
+ 'NACO' => 'NXCO',
162
+ 'PEDA' => 'PXDA',
163
+ 'PEDO' => 'PXDO',
164
+ 'PENE' => 'PXNE',
165
+ 'PIPI' => 'PXPI',
166
+ 'PITO' => 'PXTO',
167
+ 'POPO' => 'PXPO',
168
+ 'PUTA' => 'PXTA',
169
+ 'PUTO' => 'PXTO',
170
+ 'QULO' => 'QXLO',
171
+ 'RATA' => 'RXTA',
172
+ 'ROBA' => 'RXBA',
173
+ 'ROBE' => 'RXBE',
174
+ 'ROBO' => 'RXBO',
175
+ 'RUIN' => 'RXIN',
176
+ 'SENO' => 'SXNO',
177
+ 'TETA' => 'TXTA',
178
+ 'VACA' => 'VXCA',
179
+ 'VAGA' => 'VXGA',
180
+ 'VAGO' => 'VXGO',
181
+ 'VAKA' => 'VXKA',
182
+ 'VUEI' => 'VXEI',
183
+ 'VUEY' => 'VXEY',
184
+ 'WUEI' => 'WXEI',
185
+ 'WUEY' => 'WXEY'
186
+ }.freeze
187
+
188
+ COMMON_NAMES = [
189
+ 'MARIA DEL',
190
+ 'MARIA DE LOS',
191
+ 'MARIA',
192
+ 'JOSE DE',
193
+ 'JOSE',
194
+ 'MA.',
195
+ 'MA',
196
+ 'M.',
197
+ 'J.',
198
+ 'J'
199
+ ].freeze
200
+
201
+ COMPOSED_NAMES = [
202
+ 'DA ',
203
+ 'DAS ',
204
+ 'DE ',
205
+ 'DEL ',
206
+ 'DER ',
207
+ 'DI ',
208
+ 'DIE ',
209
+ 'DD ',
210
+ 'EL ',
211
+ 'LA ',
212
+ 'LOS ',
213
+ 'LAS ',
214
+ 'LE ',
215
+ 'LES ',
216
+ 'MAC ',
217
+ 'MC ',
218
+ 'VAN ',
219
+ 'VON ',
220
+ 'Y '
221
+ ].freeze
222
+ end
223
+ end
224
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,68 @@
1
+ require 'curp_generator/birth_date'
2
+ require 'curp_generator/catalogs'
3
+ require 'curp_generator/digit_verifier'
4
+ require 'curp_generator/gender'
5
+ require 'curp_generator/name'
6
+ require 'curp_generator/state'
7
+ require 'curp_generator/version'
8
+
9
+ class CurpGenerator::Curp
10
+ include ::CurpGenerator::Catalogs
11
+
12
+ InvalidArgumentError = Class.new(StandardError)
13
+
14
+ def initialize(data={})
15
+ @first_name = data[:first_name]
16
+ @second_name = data[:second_name]
17
+ @first_last_name = data[:first_last_name]
18
+ @second_last_name = data[:second_last_name]
19
+ @birth_date = data[:birth_date]
20
+ @birth_state = data[:birth_state]
21
+ @gender = data[:gender]
22
+ end
23
+
24
+ def generate
25
+ "#{partial_curp}#{verifier_digit}"
26
+ rescue => e
27
+ raise InvalidArgumentError, e
28
+ end
29
+
30
+ private
31
+
32
+ def partial_curp
33
+ @partial_curp ||= prefix_name +
34
+ parsed_date +
35
+ gender_character +
36
+ state_character +
37
+ sufix_name +
38
+ homoclave_digit
39
+ end
40
+
41
+ def verifier_digit
42
+ CurpGenerator::DigitVerifier.generate(partial_curp)
43
+ end
44
+
45
+ def prefix_name
46
+ CurpGenerator::Name.prefix_name(@first_name, @second_name, @first_last_name, @second_last_name)
47
+ end
48
+
49
+ def parsed_date
50
+ CurpGenerator::BirthDate.generate(@birth_date)
51
+ end
52
+
53
+ def gender_character
54
+ CurpGenerator::Gender.generate(@gender)
55
+ end
56
+
57
+ def state_character
58
+ CurpGenerator::State.generate(@birth_state)
59
+ end
60
+
61
+ def sufix_name
62
+ CurpGenerator::Name.sufix_name(@first_name, @second_name, @first_last_name, @second_last_name)
63
+ end
64
+
65
+ def homoclave_digit
66
+ CurpGenerator::BirthDate.homoclave_digit(@birth_date)
67
+ end
68
+ end
@@ -0,0 +1,44 @@
1
+ require 'curp_generator/base'
2
+
3
+ class CurpGenerator::DigitVerifier < ::CurpGenerator::Base
4
+ VALID_CHARACTERS = '0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'.freeze
5
+
6
+ def initialize(partial_curp)
7
+ @partial_curp = partial_curp
8
+ end
9
+
10
+ def self.generate(partial_curp)
11
+ new(partial_curp).generate
12
+ end
13
+
14
+ def generate
15
+ validate_params
16
+ verifying_digit
17
+ end
18
+
19
+ private
20
+
21
+ def validate_params
22
+ missing_partial_curp_error! if blank_string?(@partial_curp)
23
+ invalid_size_error! if @partial_curp.size != 17
24
+ end
25
+
26
+ def missing_partial_curp_error!
27
+ raise InvalidCurpArgumentError, 'Missing partial curp'
28
+ end
29
+
30
+ def invalid_size_error!
31
+ raise InvalidCurpArgumentError, 'Invalid partial curp size'
32
+ end
33
+
34
+ def verifying_digit
35
+ length_sum = 0.0
36
+
37
+ @partial_curp.chars.each_with_index do |character, index|
38
+ length_sum += VALID_CHARACTERS.index(character) * (18 - index)
39
+ end
40
+
41
+ last_digit = 10 - (length_sum % 10)
42
+ last_digit == 10 ? '0' : last_digit.to_i.to_s
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ require 'curp_generator/base'
2
+
3
+ class CurpGenerator::Gender < ::CurpGenerator::Base
4
+ VALID_MALE_GENDERS = %w[
5
+ male
6
+ hombre
7
+ masculino
8
+ h
9
+ ].freeze
10
+
11
+ VALID_FEMALE_GENDERS = %w[
12
+ female
13
+ mujer
14
+ femenino
15
+ m
16
+ ].freeze
17
+
18
+ def initialize(gender)
19
+ @gender = gender.to_s.downcase
20
+ end
21
+
22
+ def self.generate(gender)
23
+ new(gender).generate
24
+ end
25
+
26
+ def generate
27
+ validate_params
28
+ parsed_gender
29
+ end
30
+
31
+ private
32
+
33
+ def validate_params
34
+ missing_gender_error! if blank_string?(@gender)
35
+ invalid_gender_error! if invalid_gender?
36
+ end
37
+
38
+ def invalid_gender?
39
+ !VALID_MALE_GENDERS.include?(@gender) && !VALID_FEMALE_GENDERS.include?(@gender)
40
+ end
41
+
42
+ def missing_gender_error!
43
+ raise InvalidCurpArgumentError, 'Missing gender'
44
+ end
45
+
46
+ def invalid_gender_error!
47
+ raise InvalidCurpArgumentError, "Available gender options are #{VALID_MALE_GENDERS + VALID_FEMALE_GENDERS}"
48
+ end
49
+
50
+ def parsed_gender
51
+ VALID_MALE_GENDERS.include?(@gender) ? 'H' : 'M'
52
+ end
53
+ end
@@ -0,0 +1,103 @@
1
+ require 'curp_generator/base'
2
+
3
+ class CurpGenerator::Name < ::CurpGenerator::Base
4
+ def initialize(first_name, second_name, first_last_name, second_last_name)
5
+ @first_name = parse_attribute(first_name&.upcase)
6
+ @second_name = parse_attribute(second_name&.upcase)
7
+ @first_last_name = parse_attribute(first_last_name&.upcase)
8
+ @second_last_name = parse_attribute(second_last_name&.upcase)
9
+ end
10
+
11
+ def self.prefix_name(first_name, second_name, first_last_name, second_last_name)
12
+ new(first_name, second_name, first_last_name, second_last_name).prefix_name
13
+ end
14
+
15
+ def self.sufix_name(first_name, second_name, first_last_name, second_last_name)
16
+ new(first_name, second_name, first_last_name, second_last_name).sufix_name
17
+ end
18
+
19
+ def generate
20
+ validate_params
21
+ end
22
+
23
+ def prefix_name
24
+ generate
25
+ FORBIDDEN_WORDS[prefix_consonants] || prefix_consonants
26
+ end
27
+
28
+ def sufix_name
29
+ generate
30
+ sufix_consonants
31
+ end
32
+
33
+ private
34
+
35
+ def validate_params
36
+ missing_first_name_error! if blank_string?(@first_name)
37
+ missing_first_last_name_error! if blank_string?(@first_last_name)
38
+ end
39
+
40
+ def missing_first_name_error!
41
+ raise InvalidCurpArgumentError, 'Missing first name'
42
+ end
43
+
44
+ def missing_first_last_name_error!
45
+ raise InvalidCurpArgumentError, 'Missing first last name'
46
+ end
47
+
48
+ def prefix_consonants
49
+ @prefix_consonants ||=
50
+ first_character(@first_last_name) +
51
+ next_vowel(@first_last_name) +
52
+ first_character(@second_last_name) +
53
+ first_character(valid_first_name)
54
+ end
55
+
56
+ def sufix_consonants
57
+ next_consonant(@first_last_name) +
58
+ next_consonant(@second_last_name) +
59
+ next_consonant(valid_first_name)
60
+ end
61
+
62
+ def valid_first_name
63
+ valid_second_name? ? @second_name : @first_name
64
+ end
65
+
66
+ def valid_second_name?
67
+ COMMON_NAMES.include?(@first_name) && !blank_string?(@second_name)
68
+ end
69
+
70
+ def first_character(str)
71
+ return 'X' if blank_string?(str)
72
+
73
+ str[0].upcase
74
+ end
75
+
76
+ def next_consonant(str)
77
+ return 'X' if blank_string?(str)
78
+
79
+ consonants = remove_vowels(str)
80
+ consonants.size.zero? ? 'X' : consonants[0].upcase
81
+ end
82
+
83
+ def next_vowel(str)
84
+ return 'X' if blank_string?(str)
85
+
86
+ vowels = remove_consonants(str)
87
+ vowels.size.zero? ? 'X' : vowels[0].upcase
88
+ end
89
+
90
+ def remove_vowels(str)
91
+ new_str = removing_first_char(str)
92
+ new_str.downcase.tr('aeiou', '')
93
+ end
94
+
95
+ def remove_consonants(str)
96
+ new_str = removing_first_char(str)
97
+ new_str.downcase.tr('^aeiou', '')
98
+ end
99
+
100
+ def removing_first_char(str)
101
+ str[1..]
102
+ end
103
+ end
@@ -0,0 +1,31 @@
1
+ require 'curp_generator/base'
2
+
3
+ class CurpGenerator::State < ::CurpGenerator::Base
4
+ include CurpGenerator::Catalogs
5
+
6
+ def initialize(birth_state)
7
+ @birth_state = remove_special_chars(birth_state&.upcase)
8
+ end
9
+
10
+ def self.generate(birth_state)
11
+ new(birth_state).generate
12
+ end
13
+
14
+ def generate
15
+ invalid_params? ? missing_birth_state_error! : parsed_state
16
+ end
17
+
18
+ private
19
+
20
+ def invalid_params?
21
+ blank_string?(@birth_state)
22
+ end
23
+
24
+ def missing_birth_state_error!
25
+ raise InvalidCurpArgumentError, 'Missing birth state argument'
26
+ end
27
+
28
+ def parsed_state
29
+ STATES[@birth_state.upcase] || 'NE'
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module CurpGenerator
2
+ VERSION = '1.1.2'.freeze
3
+ end
@@ -1 +1,11 @@
1
- require 'curp'
1
+ require 'curp_generator/base'
2
+ require 'curp_generator/birth_date'
3
+ require 'curp_generator/catalogs'
4
+ require 'curp_generator/curp'
5
+ require 'curp_generator/digit_verifier'
6
+ require 'curp_generator/gender'
7
+ require 'curp_generator/name'
8
+ require 'curp_generator/state'
9
+ require 'curp_generator/version'
10
+
11
+ module CurpGenerator; end
metadata CHANGED
@@ -1,37 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curp_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Carlos Estebes
8
8
  - Manuel de la Torre
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-11-03 00:00:00.000000000 Z
12
+ date: 2022-05-03 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description:
15
- email:
14
+ description:
15
+ email:
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - lib/catalogs.rb
21
- - lib/curp.rb
22
20
  - lib/curp_generator.rb
23
- - lib/element.rb
24
- - lib/helpers.rb
25
- - lib/string_format.rb
26
- - lib/version.rb
21
+ - lib/curp_generator/base.rb
22
+ - lib/curp_generator/birth_date.rb
23
+ - lib/curp_generator/catalogs.rb
24
+ - lib/curp_generator/curp.rb
25
+ - lib/curp_generator/digit_verifier.rb
26
+ - lib/curp_generator/gender.rb
27
+ - lib/curp_generator/name.rb
28
+ - lib/curp_generator/state.rb
29
+ - lib/curp_generator/version.rb
27
30
  homepage: https://github.com/yotepresto-com/curp-generator
28
31
  licenses:
29
32
  - MIT
30
33
  metadata:
34
+ rubygems_mfa_required: 'true'
31
35
  homepage_uri: https://github.com/yotepresto-com/curp-generator
32
36
  source_code_uri: https://github.com/yotepresto-com/curp-generator
33
37
  changelog_uri: https://github.com/yotepresto-com/curp-generator/CHANGELOG.md
34
- post_install_message:
38
+ post_install_message:
35
39
  rdoc_options: []
36
40
  require_paths:
37
41
  - lib
@@ -46,8 +50,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
50
  - !ruby/object:Gem::Version
47
51
  version: '0'
48
52
  requirements: []
49
- rubygems_version: 3.0.6
50
- signing_key:
53
+ rubygems_version: 3.0.3.1
54
+ signing_key:
51
55
  specification_version: 4
52
56
  summary: Generates a mexican CURP given the information of a person
53
57
  test_files: []
data/lib/catalogs.rb DELETED
@@ -1,156 +0,0 @@
1
- module CurpGenerator::Catalogs
2
- VALID_CHARACTERS = '0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'.freeze
3
-
4
- STATES = {
5
- 'AGUASCALIENTES' => 'AS',
6
- 'BAJA CALIFORNIA NORTE' => 'BC',
7
- 'BAJA CALIFORNIA SUR' => 'BS',
8
- 'CAMPECHE' => 'CC',
9
- 'CHIAPAS' => 'CS',
10
- 'CHIHUAHUA' => 'CH',
11
- 'CIUDAD DE MEXICO' => 'DF',
12
- 'COAHUILA' => 'CL',
13
- 'COLIMA' => 'CM',
14
- 'DURANGO' => 'DG',
15
- 'GUANAJUATO' => 'GT',
16
- 'GUERRERO' => 'GR',
17
- 'HIDALGO' => 'HG',
18
- 'JALISCO' => 'JC',
19
- 'MEXICO' => 'MC',
20
- 'MICHOACAN' => 'MN',
21
- 'MORELOS' => 'MS',
22
- 'NAYARIT' => 'NT',
23
- 'NUEVO LEON' => 'NL',
24
- 'OAXACA' => 'OC',
25
- 'PUEBLA' => 'PL',
26
- 'QUERETARO' => 'QT',
27
- 'QUINTANA ROO' => 'QR',
28
- 'SAN LUIS POTOSI' => 'SP',
29
- 'SINALOA' => 'SL',
30
- 'SONORA' => 'SR',
31
- 'TABASCO' => 'TC',
32
- 'TAMAULIPAS' => 'TS',
33
- 'TLAXCALA' => 'TL',
34
- 'VERACRUZ' => 'VZ',
35
- 'YUCATAN' => 'YN',
36
- 'ZACATECAS' => 'ZS'
37
- }.freeze
38
-
39
- FORBIDDEN_WORDS = {
40
- 'BACA' => 'BXCA',
41
- 'LOCO' => 'LXCO',
42
- 'BAKA' => 'BXKA',
43
- 'BUEI' => 'BXEI',
44
- 'BUEY' => 'BXEY',
45
- 'CACA' => 'CXCA',
46
- 'CACO' => 'CXCO',
47
- 'CAGA' => 'CXGA',
48
- 'CAGO' => 'CXGO',
49
- 'CAKA' => 'CXKA',
50
- 'CAKO' => 'CXKO',
51
- 'COGE' => 'CXGE',
52
- 'COGI' => 'CXGI',
53
- 'COJA' => 'CXJA',
54
- 'COJE' => 'CXJE',
55
- 'COJI' => 'CXJI',
56
- 'COJO' => 'CXJO',
57
- 'COLA' => 'CXLA',
58
- 'CULO' => 'CXLO',
59
- 'FALO' => 'FXLO',
60
- 'FETO' => 'FXTO',
61
- 'GETA' => 'GXTA',
62
- 'GUEI' => 'GXEI',
63
- 'GUEY' => 'GXEY',
64
- 'JETA' => 'JXTA',
65
- 'JOTO' => 'JXTO',
66
- 'KACA' => 'KXCA',
67
- 'KACO' => 'KXCO',
68
- 'KAGA' => 'KXGA',
69
- 'KAGO' => 'KXGO',
70
- 'KAKA' => 'KXKA',
71
- 'KAKO' => 'KXKO',
72
- 'KOGE' => 'KXGE',
73
- 'KOGI' => 'KXGI',
74
- 'KOJA' => 'KXJA',
75
- 'KOJE' => 'KXJE',
76
- 'KOJI' => 'KXJI',
77
- 'KOJO' => 'KXJO',
78
- 'KOLA' => 'KXLA',
79
- 'KULO' => 'KXLO',
80
- 'LILO' => 'LXLO',
81
- 'LOKA' => 'LXKA',
82
- 'LOKO' => 'LXKO',
83
- 'MAME' => 'MXME',
84
- 'MAMO' => 'MXMO',
85
- 'MEAR' => 'MXAR',
86
- 'MEAS' => 'MXAS',
87
- 'MEON' => 'MXON',
88
- 'MIAR' => 'MXAR',
89
- 'MION' => 'MXON',
90
- 'MOCO' => 'MXCO',
91
- 'MOKO' => 'MXKO',
92
- 'MULA' => 'MXLA',
93
- 'MULO' => 'MXLO',
94
- 'NACA' => 'NXCA',
95
- 'NACO' => 'NXCO',
96
- 'PEDA' => 'PXDA',
97
- 'PEDO' => 'PXDO',
98
- 'PENE' => 'PXNE',
99
- 'PIPI' => 'PXPI',
100
- 'PITO' => 'PXTO',
101
- 'POPO' => 'PXPO',
102
- 'PUTA' => 'PXTA',
103
- 'PUTO' => 'PXTO',
104
- 'QULO' => 'QXLO',
105
- 'RATA' => 'RXTA',
106
- 'ROBA' => 'RXBA',
107
- 'ROBE' => 'RXBE',
108
- 'ROBO' => 'RXBO',
109
- 'RUIN' => 'RXIN',
110
- 'SENO' => 'SXNO',
111
- 'TETA' => 'TXTA',
112
- 'VACA' => 'VXCA',
113
- 'VAGA' => 'VXGA',
114
- 'VAGO' => 'VXGO',
115
- 'VAKA' => 'VXKA',
116
- 'VUEI' => 'VXEI',
117
- 'VUEY' => 'VXEY',
118
- 'WUEI' => 'WXEI',
119
- 'WUEY' => 'WXEY'
120
- }.freeze
121
-
122
- COMMON_NAMES = [
123
- 'MARIA DEL',
124
- 'MARIA DE LOS',
125
- 'MARIA',
126
- 'JOSE DE',
127
- 'JOSE',
128
- 'MA.',
129
- 'MA',
130
- 'M.',
131
- 'J.',
132
- 'J'
133
- ].freeze
134
-
135
- COMPOSED_NAMES = [
136
- 'DA ',
137
- 'DAS ',
138
- 'DE ',
139
- 'DEL ',
140
- 'DER ',
141
- 'DI ',
142
- 'DIE ',
143
- 'DD ',
144
- 'EL ',
145
- 'LA ',
146
- 'LOS ',
147
- 'LAS ',
148
- 'LE ',
149
- 'LES ',
150
- 'MAC ',
151
- 'MC ',
152
- 'VAN ',
153
- 'VON ',
154
- 'Y '
155
- ].freeze
156
- end
data/lib/curp.rb DELETED
@@ -1,98 +0,0 @@
1
- require 'version'
2
- require 'catalogs'
3
- require 'element'
4
- require 'helpers'
5
-
6
- class CurpGenerator::Curp
7
- include CurpGenerator::Catalogs
8
- include CurpGenerator::Helpers
9
-
10
- MissingParamError = Class.new(StandardError)
11
-
12
- PARAMS_TO_VALIDATE = %w(
13
- first_last_name
14
- first_name
15
- birth_date
16
- birth_state
17
- gender
18
- ).freeze
19
-
20
- def initialize(data = {})
21
- @first_name = data.dig(:first_name)
22
- @second_name = data.dig(:second_name)
23
- @first_last_name = parse_attribute(data.dig(:first_last_name))
24
- @second_last_name = parse_attribute(data.dig(:second_last_name)) || ''
25
- @birth_date = data.dig(:birth_date)
26
- @birth_state = parse_attribute(data.dig(:birth_state))
27
- @gender = data.dig(:gender)
28
- end
29
-
30
- def generate
31
- validate_params
32
-
33
- prefix = partial_curp
34
- prefix + verifying_digit(prefix)
35
- end
36
-
37
- private
38
-
39
- def validate_params
40
- PARAMS_TO_VALIDATE.each do |param|
41
- raise MissingParamError, "Missing #{param}" if blank_string?(instance_variable_get("@#{param}"))
42
- end
43
- end
44
-
45
- def partial_curp
46
- validate_first_four_curp_digits +
47
- parse_date(@birth_date, "%y") +
48
- parse_date(@birth_date, "%m") +
49
- parse_date(@birth_date, "%d") +
50
- gender_character +
51
- state_code +
52
- first_last_name_element.next_consonant +
53
- second_last_name_element.next_consonant +
54
- first_name_element.next_consonant +
55
- homoclave_digit
56
- end
57
-
58
- def validate_first_four_curp_digits
59
- FORBIDDEN_WORDS.dig(first_four_curp_digits) || first_four_curp_digits
60
- end
61
-
62
- def gender_character
63
- @gender == 'male' ? 'H' : 'M'
64
- end
65
-
66
- def state_code
67
- STATES.dig(@birth_state.upcase) || 'NE'
68
- end
69
-
70
- def homoclave_digit
71
- @birth_date.year < 2000 ? '0' : 'A'
72
- end
73
-
74
- def first_four_curp_digits
75
- @first_four_curp_digits ||=
76
- first_last_name_element.first_character +
77
- first_last_name_element.next_vowel +
78
- second_last_name_element.first_character +
79
- first_name_element.first_character
80
- end
81
-
82
- def first_last_name_element
83
- @first_last_name_element ||= CurpGenerator::Element.new(@first_last_name)
84
- end
85
-
86
- def second_last_name_element
87
- @second_last_name_element ||= CurpGenerator::Element.new(@second_last_name)
88
- end
89
-
90
- def first_name_element
91
- @first_name_element ||= CurpGenerator::Element.new(validate_first_name)
92
- end
93
-
94
- def validate_first_name
95
- name = parse_attribute(@first_name)
96
- COMMON_NAMES.include?(name) ? @second_name : name
97
- end
98
- end
data/lib/element.rb DELETED
@@ -1,45 +0,0 @@
1
- require 'helpers'
2
- require 'string_format'
3
-
4
- class CurpGenerator::Element
5
- include CurpGenerator::Helpers
6
-
7
- attr_accessor :name, :consonant_index, :vowel_index
8
-
9
- def initialize(name)
10
- @name = name
11
- @consonant_index = 0
12
- @vowel_index = 0
13
- end
14
-
15
- def first_character
16
- return 'X' if blank_string?(name)
17
-
18
- character = name[0].upcase
19
- update_next_index_attribute(character)
20
- character == 'Ñ' ? 'X' : character
21
- end
22
-
23
- def next_consonant
24
- return 'X' if blank_string?(name)
25
-
26
- consonants = CurpGenerator::StringFormat.new(name).remove_vowels.upcase
27
- consonants.size < 2 ? consonants[0] : consonants[consonant_index]
28
- end
29
-
30
- def next_vowel
31
- return 'X' if blank_string?(name)
32
-
33
- consonants = CurpGenerator::StringFormat.new(name).remove_consonants.upcase
34
- consonants.size < 2 ? 'X' : consonants[vowel_index]
35
- end
36
-
37
- private
38
-
39
- def update_next_index_attribute(character)
40
- new_consonant_value = CurpGenerator::StringFormat.new(character).consonant? ? 1 : 0
41
- new_vowel_value = CurpGenerator::StringFormat.new(character).vowel? ? 1 : 0
42
- self.consonant_index = new_consonant_value
43
- self.vowel_index = new_vowel_value
44
- end
45
- end
data/lib/helpers.rb DELETED
@@ -1,41 +0,0 @@
1
- require 'date'
2
- require 'catalogs'
3
- require 'string_format'
4
-
5
- module CurpGenerator::Helpers
6
- include CurpGenerator::Catalogs
7
-
8
- def verifying_digit(partial_curp)
9
- length_sum = 0.0
10
-
11
- partial_curp.split('').each_with_index do |character, index|
12
- length_sum += VALID_CHARACTERS.index(character) * (18 - index)
13
- end
14
-
15
- last_digit = 10 - (length_sum % 10)
16
- last_digit == 10 ? '0' : last_digit.to_i.to_s
17
- end
18
-
19
- def remove_composed_names(name)
20
- name = name.upcase
21
-
22
- COMPOSED_NAMES.each do |composed|
23
- next unless name.include?(composed)
24
- name = name.gsub(composed, '')
25
- end
26
- name
27
- end
28
-
29
- def parse_attribute(attribute)
30
- return if blank_string?(attribute)
31
- CurpGenerator::StringFormat.new(remove_composed_names(attribute)).str
32
- end
33
-
34
- def parse_date(date, format)
35
- date.strftime(format)
36
- end
37
-
38
- def blank_string?(value)
39
- value.to_s.strip.empty?
40
- end
41
- end
data/lib/string_format.rb DELETED
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CurpGenerator::StringFormat
4
-
5
- attr_accessor :str
6
-
7
- def initialize(str)
8
- @str = remove_special_chars(normalize(str.strip))
9
- end
10
-
11
- def remove_vowels
12
- str.downcase.tr('aeiou', '')
13
- end
14
-
15
- def remove_consonants
16
- str.downcase.tr('^aeiou', '')
17
- end
18
-
19
- def vowel?
20
- %w(A E I O U).include?(str.upcase)
21
- end
22
-
23
- def consonant?
24
- !vowel?
25
- end
26
-
27
- def first_vowel
28
- str.downcase.match(/a|e|i|o|u/).to_s.upcase
29
- end
30
-
31
- private
32
-
33
- def normalize(string)
34
- string&.tr(
35
- "ÀàÁáÄäÈèÉéËëÌìÍíÏïÒòÓóÖöÙùÚúÜüÑñ",
36
- "AaAaAaEeEeEeIiIiIiOoOoOoUuUuUuNn"
37
- )
38
- end
39
-
40
- def remove_special_chars(string)
41
- string&.gsub(/[\.\'\d-]/, "")
42
- end
43
- end
data/lib/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module CurpGenerator
2
- VERSION = '1.0.0'.freeze
3
- end