br-utils 0.1.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/.gitignore +120 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +348 -0
- data/Rakefile +6 -0
- data/examples/boleto_usage_example.rb +79 -0
- data/examples/cep_usage_example.rb +148 -0
- data/examples/cnh_usage_example.rb +120 -0
- data/examples/cnpj_usage_example.rb +227 -0
- data/examples/cpf_usage_example.rb +237 -0
- data/examples/currency_usage_example.rb +266 -0
- data/examples/date_usage_example.rb +259 -0
- data/examples/email_usage_example.rb +321 -0
- data/examples/legal_nature_usage_example.rb +437 -0
- data/examples/legal_process_usage_example.rb +444 -0
- data/examples/license_plate_usage_example.rb +440 -0
- data/examples/phone_usage_example.rb +595 -0
- data/examples/pis_usage_example.rb +588 -0
- data/examples/renavam_usage_example.rb +499 -0
- data/examples/voter_id_usage_example.rb +573 -0
- data/lib/brazilian-utils/boleto-utils.rb +176 -0
- data/lib/brazilian-utils/cep-utils.rb +330 -0
- data/lib/brazilian-utils/cnh-utils.rb +88 -0
- data/lib/brazilian-utils/cnpj-utils.rb +202 -0
- data/lib/brazilian-utils/cpf-utils.rb +192 -0
- data/lib/brazilian-utils/currency-utils.rb +226 -0
- data/lib/brazilian-utils/data/legal_process_ids.json +38 -0
- data/lib/brazilian-utils/date-utils.rb +244 -0
- data/lib/brazilian-utils/email-utils.rb +54 -0
- data/lib/brazilian-utils/legal-nature-utils.rb +235 -0
- data/lib/brazilian-utils/legal-process-utils.rb +240 -0
- data/lib/brazilian-utils/license-plate-utils.rb +279 -0
- data/lib/brazilian-utils/phone-utils.rb +272 -0
- data/lib/brazilian-utils/pis-utils.rb +151 -0
- data/lib/brazilian-utils/renavam-utils.rb +113 -0
- data/lib/brazilian-utils/voter-id-utils.rb +165 -0
- metadata +123 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
require 'brazilian-utils/renavam-utils'
|
|
2
|
+
|
|
3
|
+
include BrazilianUtils::RENAVAMUtils
|
|
4
|
+
|
|
5
|
+
puts "=" * 80
|
|
6
|
+
puts "Brazilian RENAVAM Utils - Usage Examples"
|
|
7
|
+
puts "=" * 80
|
|
8
|
+
|
|
9
|
+
# ============================================================================
|
|
10
|
+
# Section 1: Validating Valid RENAVAM Numbers
|
|
11
|
+
# ============================================================================
|
|
12
|
+
puts "\n1. Validating Valid RENAVAM Numbers"
|
|
13
|
+
puts "-" * 80
|
|
14
|
+
|
|
15
|
+
valid_renavams = [
|
|
16
|
+
'86769597308'
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
# Calculate a few valid RENAVAMs to demonstrate
|
|
20
|
+
test_bases = ['1234567890', '9876543210', '5555555550', '0123456789', '8676959730']
|
|
21
|
+
test_bases.each do |base|
|
|
22
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
23
|
+
valid_renavams << (base + dv.to_s)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
valid_renavams.each do |renavam|
|
|
27
|
+
valid = is_valid_renavam(renavam)
|
|
28
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
29
|
+
puts " #{renavam.ljust(15)} → #{status}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# ============================================================================
|
|
33
|
+
# Section 2: Validating Invalid RENAVAM Numbers
|
|
34
|
+
# ============================================================================
|
|
35
|
+
puts "\n2. Validating Invalid RENAVAM Numbers"
|
|
36
|
+
puts "-" * 80
|
|
37
|
+
|
|
38
|
+
invalid_renavams = [
|
|
39
|
+
'12345678901', # Wrong checksum
|
|
40
|
+
'1234567890a', # Contains letter
|
|
41
|
+
'12345678 901', # Contains space
|
|
42
|
+
'12345678', # Too short
|
|
43
|
+
'123456789012', # Too long
|
|
44
|
+
'00000000000', # All zeros
|
|
45
|
+
'11111111111', # All ones
|
|
46
|
+
'99999999999', # All nines
|
|
47
|
+
'', # Empty
|
|
48
|
+
'12345-678901', # Contains hyphen
|
|
49
|
+
'123.456.789.01' # Contains dots
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
invalid_renavams.each do |renavam|
|
|
53
|
+
valid = is_valid_renavam(renavam)
|
|
54
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
55
|
+
puts " #{renavam.ljust(20)} → #{status}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# ============================================================================
|
|
59
|
+
# Section 3: Using the is_valid Alias
|
|
60
|
+
# ============================================================================
|
|
61
|
+
puts "\n3. Using the is_valid Alias"
|
|
62
|
+
puts "-" * 80
|
|
63
|
+
|
|
64
|
+
test_renavams = ['86769597308', '12345678901', '11111111111']
|
|
65
|
+
|
|
66
|
+
test_renavams.each do |renavam|
|
|
67
|
+
if is_valid(renavam)
|
|
68
|
+
puts " ✓ #{renavam} is valid"
|
|
69
|
+
else
|
|
70
|
+
puts " ✗ #{renavam} is invalid"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# ============================================================================
|
|
75
|
+
# Section 4: Using the valid? Alias
|
|
76
|
+
# ============================================================================
|
|
77
|
+
puts "\n4. Using the valid? Alias"
|
|
78
|
+
puts "-" * 80
|
|
79
|
+
|
|
80
|
+
test_renavams.each do |renavam|
|
|
81
|
+
result = valid?(renavam)
|
|
82
|
+
puts " valid?('#{renavam}') → #{result}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# ============================================================================
|
|
86
|
+
# Section 5: Understanding the Verification Digit Calculation
|
|
87
|
+
# ============================================================================
|
|
88
|
+
puts "\n5. Understanding the Verification Digit Calculation"
|
|
89
|
+
puts "-" * 80
|
|
90
|
+
|
|
91
|
+
puts " Example: RENAVAM 86769597308"
|
|
92
|
+
puts
|
|
93
|
+
|
|
94
|
+
renavam = '86769597308'
|
|
95
|
+
base = renavam[0..9]
|
|
96
|
+
expected_dv = renavam[10].to_i
|
|
97
|
+
|
|
98
|
+
puts " Full RENAVAM: #{renavam}"
|
|
99
|
+
puts " Base (first 10 digits): #{base}"
|
|
100
|
+
puts " Verification digit (11th digit): #{expected_dv}"
|
|
101
|
+
puts
|
|
102
|
+
puts " Calculation steps:"
|
|
103
|
+
puts " 1. Base digits: #{base.chars.join(' ')}"
|
|
104
|
+
puts " 2. Reversed: #{base.reverse.chars.join(' ')}"
|
|
105
|
+
puts " 3. Weights: 2 3 4 5 6 7 8 9 2 3"
|
|
106
|
+
puts
|
|
107
|
+
|
|
108
|
+
# Calculate manually
|
|
109
|
+
reversed = base.reverse.chars.map(&:to_i)
|
|
110
|
+
weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3]
|
|
111
|
+
products = reversed.zip(weights).map { |d, w| d * w }
|
|
112
|
+
|
|
113
|
+
puts " 4. Products: #{products.join(' ')}"
|
|
114
|
+
sum = products.sum
|
|
115
|
+
puts " 5. Sum: #{sum}"
|
|
116
|
+
puts " 6. Sum % 11: #{sum % 11}"
|
|
117
|
+
puts " 7. 11 - (sum % 11): #{11 - (sum % 11)}"
|
|
118
|
+
calculated_dv = 11 - (sum % 11)
|
|
119
|
+
final_dv = calculated_dv >= 10 ? 0 : calculated_dv
|
|
120
|
+
puts " 8. Final DV: #{final_dv} #{final_dv >= 10 ? '(>= 10, so use 0)' : ''}"
|
|
121
|
+
puts
|
|
122
|
+
puts " Verification: #{final_dv == expected_dv ? '✓ Matches!' : '✗ Does not match'}"
|
|
123
|
+
|
|
124
|
+
# ============================================================================
|
|
125
|
+
# Section 6: Validating RENAVAM List
|
|
126
|
+
# ============================================================================
|
|
127
|
+
puts "\n6. Validating RENAVAM List"
|
|
128
|
+
puts "-" * 80
|
|
129
|
+
|
|
130
|
+
renavam_list = [
|
|
131
|
+
'86769597308',
|
|
132
|
+
'12345678901',
|
|
133
|
+
'11111111111',
|
|
134
|
+
'1234567890a',
|
|
135
|
+
'12345678',
|
|
136
|
+
'00000000000'
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
# Add some calculated valid ones
|
|
140
|
+
5.times do |i|
|
|
141
|
+
base = (i * 987654321).to_s.rjust(10, '0')[0..9]
|
|
142
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
143
|
+
renavam_list << (base + dv.to_s)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
puts " Validating #{renavam_list.length} RENAVAM numbers:"
|
|
147
|
+
puts
|
|
148
|
+
|
|
149
|
+
valid_count = 0
|
|
150
|
+
invalid_count = 0
|
|
151
|
+
|
|
152
|
+
renavam_list.each do |renavam|
|
|
153
|
+
if valid?(renavam)
|
|
154
|
+
valid_count += 1
|
|
155
|
+
puts " ✓ #{renavam}"
|
|
156
|
+
else
|
|
157
|
+
invalid_count += 1
|
|
158
|
+
puts " ✗ #{renavam.ljust(15)} [INVALID]"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
puts
|
|
163
|
+
puts " Summary:"
|
|
164
|
+
puts " Valid: #{valid_count}"
|
|
165
|
+
puts " Invalid: #{invalid_count}"
|
|
166
|
+
puts " Total: #{renavam_list.length}"
|
|
167
|
+
|
|
168
|
+
# ============================================================================
|
|
169
|
+
# Section 7: Batch Processing
|
|
170
|
+
# ============================================================================
|
|
171
|
+
puts "\n7. Batch Processing"
|
|
172
|
+
puts "-" * 80
|
|
173
|
+
|
|
174
|
+
puts " Processing batch of vehicle registrations:"
|
|
175
|
+
puts
|
|
176
|
+
|
|
177
|
+
vehicles = [
|
|
178
|
+
{ plate: 'ABC-1234', renavam: '86769597308' },
|
|
179
|
+
{ plate: 'DEF-5678', renavam: '12345678901' },
|
|
180
|
+
{ plate: 'GHI-9012', renavam: '11111111111' }
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
# Add some valid vehicles
|
|
184
|
+
3.times do |i|
|
|
185
|
+
base = (i * 123456789).to_s.rjust(10, '0')[0..9]
|
|
186
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
187
|
+
vehicles << { plate: "XYZ-#{1000 + i}", renavam: base + dv.to_s }
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
valid_vehicles = []
|
|
191
|
+
invalid_vehicles = []
|
|
192
|
+
|
|
193
|
+
vehicles.each do |vehicle|
|
|
194
|
+
if is_valid(vehicle[:renavam])
|
|
195
|
+
valid_vehicles << vehicle
|
|
196
|
+
puts " ✓ #{vehicle[:plate].ljust(10)} - RENAVAM: #{vehicle[:renavam]}"
|
|
197
|
+
else
|
|
198
|
+
invalid_vehicles << vehicle
|
|
199
|
+
puts " ✗ #{vehicle[:plate].ljust(10)} - RENAVAM: #{vehicle[:renavam]} [INVALID]"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
puts
|
|
204
|
+
puts " Summary:"
|
|
205
|
+
puts " Valid vehicles: #{valid_vehicles.length}"
|
|
206
|
+
puts " Invalid vehicles: #{invalid_vehicles.length}"
|
|
207
|
+
|
|
208
|
+
# ============================================================================
|
|
209
|
+
# Section 8: Edge Cases - All Same Digits
|
|
210
|
+
# ============================================================================
|
|
211
|
+
puts "\n8. Edge Cases - All Same Digits"
|
|
212
|
+
puts "-" * 80
|
|
213
|
+
|
|
214
|
+
puts " RENAVAM cannot be all the same digit:"
|
|
215
|
+
|
|
216
|
+
same_digit_renavams = [
|
|
217
|
+
'00000000000',
|
|
218
|
+
'11111111111',
|
|
219
|
+
'22222222222',
|
|
220
|
+
'99999999999'
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
same_digit_renavams.each do |renavam|
|
|
224
|
+
valid = is_valid(renavam)
|
|
225
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
226
|
+
puts " #{renavam} → #{status}"
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# ============================================================================
|
|
230
|
+
# Section 9: Edge Cases - Leading Zeros
|
|
231
|
+
# ============================================================================
|
|
232
|
+
puts "\n9. Edge Cases - Leading Zeros"
|
|
233
|
+
puts "-" * 80
|
|
234
|
+
|
|
235
|
+
puts " RENAVAM can start with zeros (if checksum is valid):"
|
|
236
|
+
|
|
237
|
+
# Generate some with leading zeros
|
|
238
|
+
leading_zero_bases = ['0000000001', '0000000010', '0000000100', '0000001000']
|
|
239
|
+
|
|
240
|
+
leading_zero_bases.each do |base|
|
|
241
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
242
|
+
renavam = base + dv.to_s
|
|
243
|
+
valid = is_valid(renavam)
|
|
244
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
245
|
+
puts " #{renavam} → #{status}"
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# ============================================================================
|
|
249
|
+
# Section 10: Edge Cases - Wrong Checksum
|
|
250
|
+
# ============================================================================
|
|
251
|
+
puts "\n10. Edge Cases - Wrong Checksum"
|
|
252
|
+
puts "-" * 80
|
|
253
|
+
|
|
254
|
+
puts " Changing the verification digit makes RENAVAM invalid:"
|
|
255
|
+
|
|
256
|
+
valid_renavam = '86769597308'
|
|
257
|
+
correct_dv = valid_renavam[10]
|
|
258
|
+
|
|
259
|
+
puts " Original: #{valid_renavam} (DV: #{correct_dv})"
|
|
260
|
+
puts " Valid: #{is_valid(valid_renavam)}"
|
|
261
|
+
puts
|
|
262
|
+
|
|
263
|
+
(0..9).each do |dv|
|
|
264
|
+
next if dv.to_s == correct_dv
|
|
265
|
+
|
|
266
|
+
tampered = valid_renavam[0..9] + dv.to_s
|
|
267
|
+
valid = is_valid(tampered)
|
|
268
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
269
|
+
puts " With DV #{dv}: #{tampered} → #{status}"
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# ============================================================================
|
|
273
|
+
# Section 11: Calculating Verification Digits
|
|
274
|
+
# ============================================================================
|
|
275
|
+
puts "\n11. Calculating Verification Digits"
|
|
276
|
+
puts "-" * 80
|
|
277
|
+
|
|
278
|
+
puts " Calculating DV for various base numbers:"
|
|
279
|
+
puts
|
|
280
|
+
|
|
281
|
+
test_bases_for_dv = [
|
|
282
|
+
'0000000000',
|
|
283
|
+
'1111111110',
|
|
284
|
+
'1234567890',
|
|
285
|
+
'9876543210',
|
|
286
|
+
'0123456789'
|
|
287
|
+
]
|
|
288
|
+
|
|
289
|
+
test_bases_for_dv.each do |base|
|
|
290
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
291
|
+
renavam = base + dv.to_s
|
|
292
|
+
puts " Base: #{base} → DV: #{dv} → RENAVAM: #{renavam}"
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# ============================================================================
|
|
296
|
+
# Section 12: Weights Visualization
|
|
297
|
+
# ============================================================================
|
|
298
|
+
puts "\n12. Weights Visualization"
|
|
299
|
+
puts "-" * 80
|
|
300
|
+
|
|
301
|
+
puts " The weights used for DV calculation:"
|
|
302
|
+
puts
|
|
303
|
+
puts " Position (reversed): 1 2 3 4 5 6 7 8 9 10"
|
|
304
|
+
puts " Weight: 2 3 4 5 6 7 8 9 2 3"
|
|
305
|
+
puts
|
|
306
|
+
puts " Example with RENAVAM base '1234567890':"
|
|
307
|
+
puts " Original: 1 2 3 4 5 6 7 8 9 0"
|
|
308
|
+
puts " Reversed: 0 9 8 7 6 5 4 3 2 1"
|
|
309
|
+
puts " Weights: 2 3 4 5 6 7 8 9 2 3"
|
|
310
|
+
puts " Products: 0 27 32 35 36 35 32 27 4 3"
|
|
311
|
+
|
|
312
|
+
base = '1234567890'
|
|
313
|
+
reversed = base.reverse.chars.map(&:to_i)
|
|
314
|
+
weights = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3]
|
|
315
|
+
products = reversed.zip(weights).map { |d, w| d * w }
|
|
316
|
+
sum = products.sum
|
|
317
|
+
|
|
318
|
+
puts " Sum: #{sum}"
|
|
319
|
+
puts " Sum % 11: #{sum % 11}"
|
|
320
|
+
puts " DV: #{11 - (sum % 11)}"
|
|
321
|
+
|
|
322
|
+
# ============================================================================
|
|
323
|
+
# Section 13: Format Validation
|
|
324
|
+
# ============================================================================
|
|
325
|
+
puts "\n13. Format Validation"
|
|
326
|
+
puts "-" * 80
|
|
327
|
+
|
|
328
|
+
puts " Testing various format issues:"
|
|
329
|
+
puts
|
|
330
|
+
|
|
331
|
+
format_tests = [
|
|
332
|
+
{ input: '86769597308', desc: 'Valid format' },
|
|
333
|
+
{ input: 12345678901, desc: 'Numeric (not string)' },
|
|
334
|
+
{ input: '123456789', desc: 'Too short (9 digits)' },
|
|
335
|
+
{ input: '12345678901', desc: 'Too long (12 digits)' },
|
|
336
|
+
{ input: '1234567890a', desc: 'Contains letter' },
|
|
337
|
+
{ input: '12345 67890', desc: 'Contains space' },
|
|
338
|
+
{ input: '12345-67890', desc: 'Contains hyphen' },
|
|
339
|
+
{ input: '123.456.789.01', desc: 'Contains dots' }
|
|
340
|
+
]
|
|
341
|
+
|
|
342
|
+
format_tests.each do |test|
|
|
343
|
+
valid = is_valid_renavam(test[:input])
|
|
344
|
+
status = valid ? '✓ VALID' : '✗ INVALID'
|
|
345
|
+
puts " #{status} #{test[:desc].ljust(25)} - Input: #{test[:input].inspect}"
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# ============================================================================
|
|
349
|
+
# Section 14: Error Handling
|
|
350
|
+
# ============================================================================
|
|
351
|
+
puts "\n14. Error Handling"
|
|
352
|
+
puts "-" * 80
|
|
353
|
+
|
|
354
|
+
edge_cases = [
|
|
355
|
+
nil,
|
|
356
|
+
'',
|
|
357
|
+
[],
|
|
358
|
+
{},
|
|
359
|
+
true,
|
|
360
|
+
false
|
|
361
|
+
]
|
|
362
|
+
|
|
363
|
+
edge_cases.each do |input|
|
|
364
|
+
puts " Input: #{input.inspect.ljust(20)}"
|
|
365
|
+
puts " is_valid_renavam: #{is_valid_renavam(input)}"
|
|
366
|
+
puts
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# ============================================================================
|
|
370
|
+
# Section 15: Integration Example - Vehicle Database
|
|
371
|
+
# ============================================================================
|
|
372
|
+
puts "\n15. Integration Example - Vehicle Database"
|
|
373
|
+
puts "-" * 80
|
|
374
|
+
|
|
375
|
+
puts " Simulating vehicle database validation:"
|
|
376
|
+
puts
|
|
377
|
+
|
|
378
|
+
vehicle_database = [
|
|
379
|
+
{ id: 1, owner: 'João Silva', renavam: '86769597308' },
|
|
380
|
+
{ id: 2, owner: 'Maria Santos', renavam: '12345678901' },
|
|
381
|
+
{ id: 3, owner: 'Pedro Costa', renavam: '11111111111' }
|
|
382
|
+
]
|
|
383
|
+
|
|
384
|
+
# Add some valid entries
|
|
385
|
+
3.times do |i|
|
|
386
|
+
base = (i * 234567891).to_s.rjust(10, '0')[0..9]
|
|
387
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
388
|
+
vehicle_database << {
|
|
389
|
+
id: 4 + i,
|
|
390
|
+
owner: "Owner #{4 + i}",
|
|
391
|
+
renavam: base + dv.to_s
|
|
392
|
+
}
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
puts " Validating #{vehicle_database.length} vehicle records:"
|
|
396
|
+
puts
|
|
397
|
+
|
|
398
|
+
valid_records = []
|
|
399
|
+
invalid_records = []
|
|
400
|
+
|
|
401
|
+
vehicle_database.each do |vehicle|
|
|
402
|
+
if valid?(vehicle[:renavam])
|
|
403
|
+
valid_records << vehicle
|
|
404
|
+
puts " ✓ ID #{vehicle[:id]}: #{vehicle[:owner].ljust(20)} - RENAVAM: #{vehicle[:renavam]}"
|
|
405
|
+
else
|
|
406
|
+
invalid_records << vehicle
|
|
407
|
+
puts " ✗ ID #{vehicle[:id]}: #{vehicle[:owner].ljust(20)} - RENAVAM: #{vehicle[:renavam]} [INVALID]"
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
puts
|
|
412
|
+
puts " Database Statistics:"
|
|
413
|
+
puts " Total records: #{vehicle_database.length}"
|
|
414
|
+
puts " Valid records: #{valid_records.length}"
|
|
415
|
+
puts " Invalid records: #{invalid_records.length}"
|
|
416
|
+
puts " Data quality: #{(valid_records.length * 100.0 / vehicle_database.length).round(1)}%"
|
|
417
|
+
|
|
418
|
+
# ============================================================================
|
|
419
|
+
# Section 16: Comprehensive Validation Test
|
|
420
|
+
# ============================================================================
|
|
421
|
+
puts "\n16. Comprehensive Validation Test"
|
|
422
|
+
puts "-" * 80
|
|
423
|
+
|
|
424
|
+
puts " Generating and validating 20 calculated RENAVAMs:"
|
|
425
|
+
puts
|
|
426
|
+
|
|
427
|
+
all_valid = true
|
|
428
|
+
|
|
429
|
+
20.times do |i|
|
|
430
|
+
base = (i * 50).to_s.rjust(10, '0')
|
|
431
|
+
dv = send(:calculate_renavam_dv, base + '0')
|
|
432
|
+
renavam = base + dv.to_s
|
|
433
|
+
|
|
434
|
+
valid = is_valid(renavam)
|
|
435
|
+
status = valid ? '✓' : '✗'
|
|
436
|
+
all_valid = false unless valid
|
|
437
|
+
|
|
438
|
+
puts " #{status} #{i + 1}. #{renavam}"
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
puts
|
|
442
|
+
puts " Result: #{all_valid ? '✓ All calculated RENAVAMs are valid!' : '✗ Some RENAVAMs are invalid'}"
|
|
443
|
+
|
|
444
|
+
# ============================================================================
|
|
445
|
+
# Section 17: RENAVAM Structure Visualization
|
|
446
|
+
# ============================================================================
|
|
447
|
+
puts "\n17. RENAVAM Structure Visualization"
|
|
448
|
+
puts "-" * 80
|
|
449
|
+
|
|
450
|
+
sample_renavam = '86769597308'
|
|
451
|
+
|
|
452
|
+
puts " RENAVAM: #{sample_renavam}"
|
|
453
|
+
puts
|
|
454
|
+
puts " Structure:"
|
|
455
|
+
puts " #{sample_renavam}"
|
|
456
|
+
puts " │││││││││││"
|
|
457
|
+
puts " │││││││││││└─ Verification digit (position 11): #{sample_renavam[10]}"
|
|
458
|
+
puts " └┴┴┴┴┴┴┴┴┴┴── Base number (positions 1-10): #{sample_renavam[0..9]}"
|
|
459
|
+
puts
|
|
460
|
+
puts " Total length: 11 digits"
|
|
461
|
+
|
|
462
|
+
# ============================================================================
|
|
463
|
+
# Section 18: Comparison with Similar Systems
|
|
464
|
+
# ============================================================================
|
|
465
|
+
puts "\n18. Comparison with Similar Systems"
|
|
466
|
+
puts "-" * 80
|
|
467
|
+
|
|
468
|
+
puts " RENAVAM characteristics:"
|
|
469
|
+
puts " • Length: 11 digits"
|
|
470
|
+
puts " • Format: No separators (continuous digits)"
|
|
471
|
+
puts " • Checksum: Last digit (weights: 2,3,4,5,6,7,8,9,2,3)"
|
|
472
|
+
puts " • Cannot be: All same digits"
|
|
473
|
+
puts " • Purpose: Vehicle registration identification"
|
|
474
|
+
puts
|
|
475
|
+
puts " Similar to:"
|
|
476
|
+
puts " • CPF: 11 digits with checksum"
|
|
477
|
+
puts " • PIS: 11 digits with checksum"
|
|
478
|
+
puts " • Different from: License plates (letters + numbers)"
|
|
479
|
+
|
|
480
|
+
# ============================================================================
|
|
481
|
+
# Section 20: Best Practices
|
|
482
|
+
# ============================================================================
|
|
483
|
+
puts "\n20. Best Practices"
|
|
484
|
+
puts "-" * 80
|
|
485
|
+
|
|
486
|
+
puts " When working with RENAVAM:"
|
|
487
|
+
puts
|
|
488
|
+
puts " 1. Always validate before storing in database"
|
|
489
|
+
puts " 2. Store as string to preserve leading zeros"
|
|
490
|
+
puts " 3. Do not accept formatted input (no separators)"
|
|
491
|
+
puts " 4. Reject all-same-digit patterns"
|
|
492
|
+
puts " 5. Verify checksum to ensure data integrity"
|
|
493
|
+
puts " 6. Consider adding validation at form input"
|
|
494
|
+
puts " 7. Log validation failures for security monitoring"
|
|
495
|
+
puts " 8. Use consistent method (is_valid, valid?, is_valid_renavam)"
|
|
496
|
+
|
|
497
|
+
puts "\n" + "=" * 80
|
|
498
|
+
puts "RENAVAM Utils Examples Complete!"
|
|
499
|
+
puts "=" * 80
|