Revision: 52589
Updated Code
at July 8, 2012 01:37 by mabafu
Updated Code
# Generic Module 11 validator
class Module11
protected
#returns the next validation 'digit' of the 'input'.
#It will calcultes the next 'digit' based on the
#given 'formula' (as block)
def Module11.getDigit (input, formula)
digit = 0
input.each_with_index do |item, index|
#passing the current item, its index and the whole array
#to the formula
digit += formula.call(item, index, input)
end
digit = 11 - (digit % 11)
digit = 0 if digit > 9
return digit
end
#calculates the new 'input' digits based on the given 'formula'
#and the 'size' of the desired 'output' array
def Module11.calculate (input, formula, size)
output = Array.new (input)
while output.size < size do
output << getDigit(output, formula)
end
return output
end
public
attr_reader :value
def initialize(input, formula, size, number_of_digits)
if input.kind_of? String
@value = input.scan(/\d/).collect{ |item| item.to_i }
else
@value = [0]
end
if formula.kind_of? Proc
@formula = formula
else
@formula = nil
end
if size.kind_of? Fixnum
@size = size
else
@size = 0
end
if number_of_digits.kind_of? Fixnum
@number_of_digits = number_of_digits
else
@number_of_digits = 0
end
if (@size > 0) and (@value.size > 0) and (@number_of_digits > 0) and (not @formula.nil?)
@result = Module11.calculate(@value[0,@size-@number_of_digits], @formula, @size)
else
@result = []
end
end
def inspect
"< @value = " + @value.to_s + ">"
end
def to_s
@value.join("")
end
def is_valid?
@value == @result
end
def validated
if is_valid?
self
else
Module11.new @result.join, @formula, @size, @number_of_digits
end
end
def is_obvious?
@result.join("").to_i % ("1"*@size).to_i == 0
end
def digits
if @value.size == @size
@value[@size-@number_of_digits, @number_of_digits]
else
[]
end
end
end
class Cpf < Module11
private
def Cpf.formula
Proc.new do |item, index, updatedInput|
item * (updatedInput.size + 1 - index)
end
end
public
def initialize(input)
super input, Cpf.formula, 11, 2
end
def validated
if is_valid?
self
else
Cpf.new @result.join
end
end
end
class Cnpj < Module11
private
def Cnpj.formula
Proc.new do |item, index, updatedInput|
coefs = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
item * coefs[index+13-updatedInput.size]
end
end
public
def initialize(input)
super input, Cnpj.formula, 14, 2
end
def validated
if is_valid?
self
else
Cnpj.new @result.join
end
end
end
Revision: 52588
Updated Code
at November 5, 2011 12:34 by mabafu
Updated Code
# Generic Module 11 validator
class Module11
protected
#returns the next validation 'digit' of the 'input'.
#It will calcultes the next 'digit' based on the
#given 'formula' (as block)
def Module11.getDigit (input, formula)
digit = 0
input.each_with_index do |item, index|
#passing the current item, its index and the whole matrix
#to the formula
digit += formula.call(item, index, input)
end
digit = 11 - (digit % 11)
digit = 0 if digit > 9
return digit
end
#calculates the new 'input' digits based on the given 'formula'
#and the 'size' of the desired 'output' matrix
def Module11.calculate (input, formula, size)
output = Array.new (input)
while output.size < size do
output << getDigit(output, formula)
end
return output
end
public
attr_reader :value
def initialize(input, formula, size, number_of_digits)
if input.kind_of? String
@value = input.scan(/\d/).collect{ |item| item.to_i }
else
@value = [0]
end
if formula.kind_of? Proc
@formula = formula
else
@formula = nil
end
if size.kind_of? Fixnum
@size = size
else
@size = 0
end
if number_of_digits.kind_of? Fixnum
@number_of_digits = number_of_digits
else
@number_of_digits = 0
end
if (@size > 0) and (@value.size > 0) and (@number_of_digits > 0) and (not @formula.nil?)
@result = Module11.calculate(@value[0,@size-@number_of_digits], @formula, @size)
else
@result = []
end
end
def inspect
"< @value = " + @value.to_s + ">"
end
def to_s
@value.join("")
end
def is_valid?
@value == @result
end
def validated
if is_valid?
self
else
Module11.new @result.join, @formula, @size, @number_of_digits
end
end
def is_obvious?
@result.join("").to_i % ("1"*@size).to_i == 0
end
def digits
if @value.size == @size
@value[@size-@number_of_digits, @number_of_digits]
else
[]
end
end
end
class Cpf < Module11
private
def Cpf.formula
Proc.new do |item, index, updatedInput|
item * (updatedInput.size + 1 - index)
end
end
public
def initialize(input)
super input, Cpf.formula, 11, 2
end
def validated
if is_valid?
self
else
Cpf.new @result.join
end
end
end
class Cnpj < Module11
private
def Cnpj.formula
Proc.new do |item, index, updatedInput|
coefs = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
item * coefs[index+13-updatedInput.size]
end
end
public
def initialize(input)
super input, Cnpj.formula, 14, 2
end
def validated
if is_valid?
self
else
Cnpj.new @result.join
end
end
end
Revision: 52587
Updated Code
at October 27, 2011 08:26 by mabafu
Updated Code
# Generic Module 11 validator
class Module11
protected
#returns the next validation 'digit' of the 'input'.
#It will calcultes the next 'digit' based on the
#given 'formula' (as block)
def Module11.getDigit (input, formula)
digit = 0
input.each_with_index do |item, index|
#passing the current item, its index and the whole matrix
#to the formula
digit += formula.call(item, index, input)
end
digit = 11 - (digit % 11)
digit = 0 if digit > 9
return digit
end
#calculates the new 'input' digits based on the given 'formula'
#and the 'size' of the desired 'output' matrix
def Module11.calculate (input, formula, size)
output = Array.new (input)
while output.size < size do
output << getDigit(output, formula)
end
return output
end
public
attr_reader :value
def initialize(input, formula, size, number_of_digits)
if input.kind_of? String
@value = input.scan(/\d/).collect{ |item| item.to_i }
else
@value = [0]
end
if formula.kind_of? Proc
@formula = formula
else
@formula = nil
end
if size.kind_of? Fixnum
@size = size
else
@size = 0
end
if number_of_digits.kind_of? Fixnum
@number_of_digits = number_of_digits
else
@number_of_digits = 0
end
if (@size > 0) and (@value.size > 0) and (@number_of_digits > 0) and (not @formula.nil?)
@result = Module11.calculate(@value, @formula, @size)
else
@result = []
end
end
def inspect
"< @value = " + @value.to_s + ">"
end
def to_s
@value.join("")
end
def is_valid?
valueDigits = @value[@size-@number_of_digits, @number_of_digits]
resultDigits = @result[@size-@number_of_digits, @number_of_digits]
@value.size == @size and (valueDigits == resultDigits )
end
def validated
if is_valid?
self
else
Module11.new @result.join, @formula, @size, @number_of_digits
end
end
def is_obvious?
@result.join("").to_i % ("1"*@size).to_i == 0
end
def digits
if @value.size == @size
@value[@size-@number_of_digits, @number_of_digits]
else
[]
end
end
end
class Cpf < Module11
private
def Cpf.formula
Proc.new do |item, index, updatedInput|
item * (updatedInput.size + 1 - index)
end
end
public
def initialize(input)
super input, Cpf.formula, 11, 2
end
def validated
if is_valid?
self
else
Cpf.new @result.join
end
end
end
class Cnpj < Module11
private
def Cnpj.formula
Proc.new do |item, index, updatedInput|
coefs = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
item * coefs[index+13-updatedInput.size]
end
end
public
def initialize(input)
super input, Cnpj.formula, 14, 2
end
def validated
if is_valid?
self
else
Cnpj.new @result.join
end
end
end
Revision: 52586
Updated Code
at October 27, 2011 05:25 by mabafu
Updated Code
# Generic Module 11 validator
class Module11
protected
#returns the next validation 'digit' of the 'input'.
#It will calcultes the next 'digit' based on the
#given 'formula' (as block)
def Module11.getDigit (input, formula)
digit = 0
input.each_with_index do |item, index|
#passing the current item, its index and the whole matrix
#to the formula
digit += formula.call(item, index, input)
end
digit = 11 - (digit % 11)
digit = 0 if digit > 9
return digit
end
#calculates the new 'input' digits based on the given 'formula'
#and the 'size' of the desired 'output' matrix
def Module11.calculate (input, formula, size)
output = Array.new (input)
while output.size < size do
output << getDigit(output, formula)
end
return output
end
public
attr_reader :value
def initialize(input, formula, size, number_of_digits)
if input.kind_of? String
@value = input.split("").collect{ |item| item.to_i }
else
@value = [0]
end
if formula.kind_of? Proc
@formula = formula
else
@formula = nil
end
if size.kind_of? Fixnum
@size = size
else
@size = 0
end
if number_of_digits.kind_of? Fixnum
@number_of_digits = number_of_digits
else
@number_of_digits = 0
end
if (@size > 0) and (@value.size > 0) and (@number_of_digits > 0) and (not @formula.nil?)
@result = Module11.calculate(@value, @formula, @size)
else
@result = []
end
end
def inspect
"< @value = " + @value.to_s + ">"
end
def to_s
@value.join("")
end
def is_valid?
valueDigits = @value[@size-@number_of_digits, @number_of_digits]
resultDigits = @result[@size-@number_of_digits, @number_of_digits]
@value.size == @size and (valueDigits == resultDigits )
end
def validated
if is_valid?
self
else
Module11.new @result.join, @formula, @size, @number_of_digits
end
end
def is_obvious?
@result.join("").to_i % ("1"*@size).to_i == 0
end
def digits
if @value.size == @size
@value[@size-@number_of_digits, @number_of_digits]
else
[]
end
end
end
class Cpf < Module11
private
def Cpf.formula
Proc.new do |item, index, updatedInput|
item * (updatedInput.size + 1 - index)
end
end
public
def initialize(input)
super input, Cpf.formula, 11, 2
end
def validated
if is_valid?
self
else
Cpf.new @result.join
end
end
end
class Cnpj < Module11
private
def Cnpj.formula
Proc.new do |item, index, updatedInput|
coefs = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
item * coefs[index+13-updatedInput.size]
end
end
public
def initialize(input)
super input, Cnpj.formula, 14, 2
end
def validated
if is_valid?
self
else
Cnpj.new @result.join
end
end
end
Revision: 52585
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at October 27, 2011 03:06 by mabafu
Initial Code
# Generic Module 11 Validation Class
class Module11
protected
#returns the next validation 'digit' of the 'input'.
#It will calcultes the next 'digit' based on the
#given 'formula' (as block)
def Module11.getDigit (input, formula)
digit = 0
input.each_with_index do |item, index|
#passing the current item, its index and the whole matrix
#to the formula
digit += formula.call(item, index, input)
end
digit = 11 - (digit % 11)
digit = 0 if digit > 9
return digit
end
#calculates the new 'input' digits based on the given 'formula'
#and the 'size' of the desired 'output' matrix
def Module11.calculate (input, formula, size)
output = Array.new (input)
while output.size < size do
output << getDigit(output, formula)
end
return output
end
public
attr_reader :value, :validated
def initialize(input, formula, size, number_of_digits)
if input.kind_of? String
@value = input.split("").collect{ |item| item.to_i }
else
@value = [0]
end
if formula.kind_of? Proc
@formula = formula
else
@formula = nil
end
if size.kind_of? Fixnum
@size = size
else
@size = 0
end
if number_of_digits.kind_of? Fixnum
@number_of_digits = number_of_digits
else
@number_of_digits = 0
end
if (@size > 0) and (@value.size > 0) and (@number_of_digits > 0) and (not @formula.nil?)
@result = Module11.calculate(@value, @formula, @size)
else
@result = []
end
if is_valid?
@validated = self
else
@validated = Module11.new @result.join, @formula, @size, @number_of_digits
end
end
def inspect
"< @value = " + @value.to_s + ">"
end
def to_s
@value.join("")
end
def is_valid?
valueDigits = @value[@size-@number_of_digits, @number_of_digits]
resultDigits = @result[@size-@number_of_digits, @number_of_digits]
@value.size == @size and (valueDigits == resultDigits )
end
def is_obvious?
@result.join("").to_i % ("1"*@size).to_i == 0
end
def digits
if @value.size == @size
@value[@size-@number_of_digits, @number_of_digits]
else
[]
end
end
end
#Cpf Validation Class
class Cpf < Module11
def initialize(input)
formula = Proc.new do |item, index, updatedInput|
item * (updatedInput.size + 1 - index)
end
super input, formula, 11, 2
end
end
#Cnpj Validation Class
class Cnpj < Module11
def initialize(input)
formula = Proc.new do |item, index, updatedInput|
coefs = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
item * coefs[index+13-updatedInput.size]
end
super input, formula, 14, 2
end
end
Initial URL
Initial Description
#About# CPF and CNPJ are self-validated codes generated by Brazilian government. Being the CPF used to identify persons and CNJP to enterprises, organizations and so on. That said, I use to code the CPF/CNPJ algorithm when learning new programming languages. With Ruby, it got very clean and powerful because it's particular way to deal with "closures" (i.e. the ruby blocks, Procs and lambdas). To use Cpf or Cnpj classes, just instantite the respective classes passing the numbers to be validated. CPF has 11 digits and CNPJ has 14. In both cases the last two digits are calculated based on the previous ones. Module11 is the parent class of Cpf and Cnpj. You can use this class if you want to implement your own Module 11 validation algorithm. In this case, inherit from Module11 and initialize the new class with the proper parameters (i.e. input, formula, size, number_of_digits)
Initial Title
CPF and CNPJ validation classes using the Brazilian Government official algorithms
Initial Tags
Initial Language
Ruby