br-cpf 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
- }