br-cpf 0.1.2 → 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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## BUNDLE
17
+ .bundle
18
+
19
+ ## PROJECT::GENERAL
20
+ coverage
21
+ rdoc
22
+ pkg
23
+ doc
24
+
25
+ ## PROJECT::SPECIFIC
26
+ tmp
27
+ *.so
28
+ *.gemspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in br-cpf.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,14 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ rake (0.8.7)
5
+ rake-compiler (0.7.1)
6
+ rake (>= 0.8.3, < 0.9)
7
+ rspec (1.3.0)
8
+
9
+ PLATFORMS
10
+ ruby
11
+
12
+ DEPENDENCIES
13
+ rake-compiler
14
+ rspec (~> 1.3.0)
data/README.rdoc CHANGED
@@ -1,6 +1,7 @@
1
1
  = BR::CPF
2
2
 
3
3
  Lib implementada em C (gera uma lib compilada nativamente) que calcula e valida CPFs.
4
+ Recomendada para Validar CPFs ou Gerar CPFs quando o sistema requer que sejam feitas mais de 1000 Validações/Gerações por segundo.
4
5
 
5
6
  == Instalação
6
7
 
@@ -8,9 +9,12 @@ Lib implementada em C (gera uma lib compilada nativamente) que calcula e valida
8
9
 
9
10
  == Exemplos
10
11
 
12
+ === Usar
11
13
  require 'rubygems'
12
14
  require 'br/cpf'
13
15
 
16
+ === Validar
17
+
14
18
  BR::CPF.valid? '00000000191'
15
19
  => true
16
20
 
@@ -20,11 +24,64 @@ Lib implementada em C (gera uma lib compilada nativamente) que calcula e valida
20
24
  BR::CPF.valid? 12345678900
21
25
  => false
22
26
 
23
- raiz = 0
27
+ === Gerar CPF
28
+
29
+ raiz = 1
24
30
  BR::CPF.new(raiz).to_s
25
31
  => '00000000191'
26
32
 
33
+ == Benchmark sobre uma implementação puro Ruby
34
+ Comparação de validação com a brcpfcnpj (Brazilian Rails)
35
+
36
+ $ cat benchmark.rb
37
+ require "rubygems"
38
+ require "br/cpf"
39
+ require "brcpfcnpj"
40
+ require "benchmark"
41
+
42
+ [1, 10, 100, 1000, 10_000, 100_000, 1_000_000].each do |n|
43
+ puts "Teste com n = #{n}"
44
+ Benchmark.bm do |x|
45
+ x.report { n.times { BR::CPF.valid?(rand(999_999_999_99).to_s.rjust(11, '0')) } }
46
+ x.report { n.times { Cpf.new(rand(999_999_999_99).to_s.rjust(11, '0')).valido? } }
47
+ end
48
+ end
49
+
50
+ Resultados
51
+
52
+ Teste com n = 1
53
+ user system total real
54
+ 0.000000 0.000000 0.000000 ( 0.000053)
55
+ 0.000000 0.000000 0.000000 ( 0.000243)
56
+ Teste com n = 10
57
+ user system total real
58
+ 0.000000 0.000000 0.000000 ( 0.000080)
59
+ 0.000000 0.000000 0.000000 ( 0.001187)
60
+ Teste com n = 100
61
+ user system total real
62
+ 0.000000 0.000000 0.000000 ( 0.002193)
63
+ 0.020000 0.000000 0.020000 ( 0.011373)
64
+ Teste com n = 1000
65
+ user system total real
66
+ 0.020000 0.000000 0.020000 ( 0.017329)
67
+ 0.150000 0.000000 0.150000 ( 0.169375)
68
+ Teste com n = 10000
69
+ user system total real
70
+ 0.100000 0.000000 0.100000 ( 0.094112)
71
+ 1.490000 0.010000 1.500000 ( 1.512164)
72
+ Teste com n = 100000
73
+ user system total real
74
+ 0.850000 0.000000 0.850000 ( 0.874577)
75
+ 15.050000 0.010000 15.060000 ( 15.193196)
76
+ Teste com n = 1000000
77
+ user system total real
78
+ 8.570000 0.010000 8.580000 ( 8.631888)
79
+ 150.620000 0.210000 150.830000 (152.158936)
80
+
81
+ == Desvantagens
82
+ Por precisar compilar a extensão em C, acaba incompatível com sistemas que não tem um compilador em C (Windows).
27
83
 
84
+ E quando o ritmo de comparação for menor que 1000 por segundo a diferença é pequena, por volta de de 0.15 segundos. Talvez o acumulo de dependência não valha a pena.
28
85
 
29
86
  == Copyright
30
87
 
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
data/ext/CPF/cpf.c CHANGED
@@ -1,7 +1,7 @@
1
1
  #include <stdlib.h>
2
2
  #include "cpf.h"
3
3
 
4
- long long calcula_digito_cpf(long long raiz){
4
+ long long calc_check_digit(long long raiz){
5
5
  int produto=0, i, digito;
6
6
  long long aux=raiz, cpf;
7
7
  lldiv_t divisao;
@@ -27,8 +27,8 @@ long long calcula_digito_cpf(long long raiz){
27
27
  }
28
28
 
29
29
 
30
- int e_cpf(long long cpf){
31
- return cpf==calcula_digito_cpf((long long)cpf / 100);
30
+ int is_valid(long long cpf){
31
+ return cpf==calc_check_digit((long long)cpf / 100);
32
32
  }
33
33
 
34
34
 
data/ext/CPF/cpf.h CHANGED
@@ -5,8 +5,8 @@
5
5
  extern "C" {
6
6
  #endif
7
7
 
8
- long long calcula_digito_cpf(long long raiz);
9
- int e_cpf(long long cpf);
8
+ long long calc_check_digit(long long raiz);
9
+ int is_valid(long long cpf);
10
10
 
11
11
  #ifdef __cplusplus
12
12
  }
@@ -0,0 +1,9 @@
1
+ require 'ffi'
2
+ module BR
3
+ module CPFWrapper
4
+ extend FFI::Library
5
+ ffi_lib File.join(File.dirname(__FILE__), "..", "..", "CPF.so")
6
+ attach_function :calc_check_digit, [:long_long], :long_long
7
+ attach_function :is_valid, [:long_long], :bool
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module BR
2
+ class CPF
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
data/lib/br/cpf.rb CHANGED
@@ -1,25 +1,49 @@
1
- require File.join(File.dirname(__FILE__), '../CPF')
1
+ require File.join(File.dirname(__FILE__), 'cpf/cpf_wrapper')
2
2
 
3
3
  module BR
4
4
  class CPF
5
- class << self
6
- alias_method :orig_valid?, :valid?
5
+
6
+ CPF_MIN = 1
7
+ CPF_MAX = 999999999
8
+
9
+ extend CPFWrapper
10
+
11
+ attr_reader :cpf, :verif
12
+
13
+ def initialize(raiz)
14
+ self.raiz = raiz
15
+ end
16
+
17
+ def valid?
18
+ @valid
19
+ end
20
+
21
+ def raiz=(raiz)
22
+ @raiz = raiz.to_i
23
+ raise ArgumentError, "raiz should be between #{CPF_MIN} and #{CPF_MAX}" if @raiz < CPF_MIN or @raiz > CPF_MAX
24
+ @cpf = self.class.calc_check_digit(@raiz)
25
+ @verif = @cpf % 100
26
+ @valid = true
27
+ end
28
+
29
+ def raiz
30
+ @raiz
7
31
  end
8
32
 
9
33
  def self.valid?(cpf)
10
34
  if cpf.is_a? String
11
- orig_valid?(cpf.to_i)
35
+ is_valid(cpf.to_i)
12
36
  else
13
- orig_valid?(cpf)
37
+ is_valid(cpf)
14
38
  end
15
39
  end
16
40
 
17
41
  def to_i
18
- @raiz * 100 + @verif
42
+ @cpf
19
43
  end
20
44
 
21
45
  def to_s
22
- "%011d" % to_i
46
+ "%011d" % @cpf
23
47
  end
24
48
  end
25
49
  end
data/spec/br-cpf_spec.rb CHANGED
@@ -2,6 +2,23 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe BR::CPF do
4
4
 
5
+ context "initializing new CPFs" do
6
+
7
+ it "should initialize correctly VALID CPFS" do
8
+ VALID_CPFS_INTEGER.each do |valid_cpf|
9
+ BR::CPF.new(valid_cpf/100).to_s.should ==
10
+ valid_cpf.to_s.rjust(11, '0')
11
+ end
12
+ end
13
+
14
+ it "should initializa correctly VALID CPFS as string" do
15
+ VALID_CPFS_STRING.each do |valid_cpf|
16
+ BR::CPF.new(valid_cpf[0,9]).to_s.should == valid_cpf
17
+ end
18
+ end
19
+
20
+ end
21
+
5
22
  context "when Fixnum" do
6
23
 
7
24
  it "should return true for valid cpfs" do
data/spec/faker_cpf.rb CHANGED
@@ -45,9 +45,9 @@ module Faker
45
45
 
46
46
  INVALID_CPFS_INTEGER = VALID_CPFS_INTEGER.collect { |cpf| cpf + 1}
47
47
 
48
- VALID_CPFS_STRING = VALID_CPFS_INTEGER.collect { |cpf| cpf.to_s }
48
+ VALID_CPFS_STRING = VALID_CPFS_INTEGER.collect { |cpf| cpf.to_s.rjust(11, '0') }
49
49
 
50
- INVALID_CPFS_STRING = INVALID_CPFS_INTEGER.collect { |cpf| cpf.to_s}
50
+ INVALID_CPFS_STRING = INVALID_CPFS_INTEGER.collect { |cpf| cpf.to_s.rjust(11, '0') }
51
51
 
52
52
  end
53
53
  end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
metadata CHANGED
@@ -1,84 +1,88 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: br-cpf
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Bruno Coimbra
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-04-16 00:00:00 -03:00
12
+ date: 2011-09-04 00:00:00.000000000 -03:00
18
13
  default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: rspec
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi
17
+ requirement: &78340280 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
23
+ type: :runtime
22
24
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 1
29
- - 2
30
- - 9
31
- version: 1.2.9
25
+ version_requirements: *78340280
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: &78340020 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
32
34
  type: :development
33
- version_requirements: *id001
34
- description: Lib implemented in C that calculates and validates CPF.
35
- email: bbcoimbra@gmail.com
35
+ prerelease: false
36
+ version_requirements: *78340020
37
+ description: ''
38
+ email:
39
+ - bbcoimbra@gmail.com
36
40
  executables: []
37
-
38
- extensions:
41
+ extensions:
39
42
  - ext/CPF/extconf.rb
40
- extra_rdoc_files:
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - Gemfile
48
+ - Gemfile.lock
41
49
  - LICENSE
42
50
  - README.rdoc
43
- files:
51
+ - Rakefile
52
+ - VERSION
44
53
  - ext/CPF/cpf.c
45
54
  - ext/CPF/cpf.h
46
55
  - ext/CPF/extconf.rb
47
- - ext/CPF/ruby_cpf.c
48
56
  - lib/br/cpf.rb
49
- - LICENSE
50
- - README.rdoc
57
+ - lib/br/cpf/cpf_wrapper.rb
58
+ - lib/br/cpf/version.rb
59
+ - spec/br-cpf_spec.rb
60
+ - spec/faker_cpf.rb
61
+ - spec/spec.opts
62
+ - spec/spec_helper.rb
51
63
  has_rdoc: true
52
- homepage: http://github.com/bbcoimbra/br-cpf
64
+ homepage: ''
53
65
  licenses: []
54
-
55
66
  post_install_message:
56
- rdoc_options:
57
- - --charset=UTF-8
58
- require_paths:
67
+ rdoc_options: []
68
+ require_paths:
59
69
  - lib
60
- required_ruby_version: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- segments:
65
- - 0
66
- version: "0"
67
- required_rubygems_version: !ruby/object:Gem::Requirement
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- segments:
72
- - 0
73
- version: "0"
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
74
82
  requirements: []
75
-
76
83
  rubyforge_project:
77
- rubygems_version: 1.3.6
84
+ rubygems_version: 1.6.2
78
85
  signing_key:
79
86
  specification_version: 3
80
- summary: Calculates and validates given CPF
81
- test_files:
82
- - spec/faker_cpf.rb
83
- - spec/spec_helper.rb
84
- - spec/br-cpf_spec.rb
87
+ summary: Lib implemented in C that calculates and validates CPF using FFI.
88
+ test_files: []
data/ext/CPF/ruby_cpf.c DELETED
@@ -1,33 +0,0 @@
1
- #include <stdlib.h>
2
- #include "ruby.h"
3
- #include "cpf.h"
4
-
5
- static VALUE t_init_cpf(VALUE self, VALUE ruby_cpf_raiz){
6
- long long cpf = 0, raiz = 0;
7
- VALUE ruby_cpf;
8
-
9
- raiz = NUM2LL(ruby_cpf_raiz);
10
- if(raiz < 1 || raiz > 999999999)
11
- rb_raise(rb_eArgError, "raiz should be greather than 0 and lesser than 999_999_999");
12
- cpf = calcula_digito_cpf((long long) raiz);
13
- ruby_cpf = LL2NUM(cpf);
14
- rb_iv_set(self, "@raiz", INT2FIX(raiz));
15
- rb_iv_set(self, "@cpf", ruby_cpf);
16
- rb_iv_set(self, "@valid", e_cpf(cpf) ? Qtrue : Qfalse );
17
- return self;
18
- }
19
-
20
- static VALUE valid_cpf(VALUE self, VALUE ruby_cpf){
21
- long long cpf = 0;
22
- cpf = (long long)NUM2LL(ruby_cpf);
23
- if(cpf == 0) return Qfalse;
24
- return e_cpf(cpf) ? Qtrue : Qfalse;
25
- }
26
-
27
- VALUE mBr, cCpf;
28
- void Init_CPF(){
29
- mBr = rb_define_module("BR");
30
- cCpf = rb_define_class_under(mBr, "CPF", rb_cObject);
31
- rb_define_method(cCpf, "initialize", t_init_cpf, 1);
32
- rb_define_singleton_method(cCpf, "valid?", valid_cpf, 1);
33
- }