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: []
|