curp_generator 1.0.0
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 +7 -0
- data/lib/catalogs.rb +156 -0
- data/lib/curp.rb +98 -0
- data/lib/curp_generator.rb +1 -0
- data/lib/element.rb +45 -0
- data/lib/helpers.rb +41 -0
- data/lib/string_format.rb +43 -0
- data/lib/version.rb +3 -0
- metadata +53 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1a65ed003039b6871fef8ca8eca44a529706baf765010619457d8955d58ad032
|
|
4
|
+
data.tar.gz: 184facb4300807434ad265dd068b1924e2ad884c29333839564efa2e79be8d9c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a3d031d50701c6554cdc9f7c024e472157c27d58d1d8c42f4ccc60399b3a4b4b824ef144a26ebf9fa56eca25c4aae41d2120d98b0b5e8fd26fe6a93dcc8a3283
|
|
7
|
+
data.tar.gz: c6647a39d66e0445feb5f1e0ccaf8508387f075916ce560750490e986d412976e5a3367bf821a9ac8103e65f0fbb611dbde2a9bccd63b7a1b37390b08ee48e75
|
data/lib/catalogs.rb
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'curp'
|
data/lib/element.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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
|
|
@@ -0,0 +1,43 @@
|
|
|
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
ADDED
metadata
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: curp_generator
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Juan Carlos Estebes
|
|
8
|
+
- Manuel de la Torre
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2020-11-03 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description:
|
|
15
|
+
email:
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/catalogs.rb
|
|
21
|
+
- lib/curp.rb
|
|
22
|
+
- lib/curp_generator.rb
|
|
23
|
+
- lib/element.rb
|
|
24
|
+
- lib/helpers.rb
|
|
25
|
+
- lib/string_format.rb
|
|
26
|
+
- lib/version.rb
|
|
27
|
+
homepage: https://github.com/yotepresto-com/curp-generator
|
|
28
|
+
licenses:
|
|
29
|
+
- MIT
|
|
30
|
+
metadata:
|
|
31
|
+
homepage_uri: https://github.com/yotepresto-com/curp-generator
|
|
32
|
+
source_code_uri: https://github.com/yotepresto-com/curp-generator
|
|
33
|
+
changelog_uri: https://github.com/yotepresto-com/curp-generator/CHANGELOG.md
|
|
34
|
+
post_install_message:
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '2.6'
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
requirements: []
|
|
49
|
+
rubygems_version: 3.0.6
|
|
50
|
+
signing_key:
|
|
51
|
+
specification_version: 4
|
|
52
|
+
summary: Generates a mexican CURP given the information of a person
|
|
53
|
+
test_files: []
|