identitycode 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8a78b100dec78b3c17fde161be9654a7d69a601
4
- data.tar.gz: abcc6067320e6bce69263e3f66965a972e04337a
3
+ metadata.gz: 8cfc172aeb2d5abd52ea44ebbadc44025ef8010c
4
+ data.tar.gz: ba6ef782a21f0173f63558d42d402a51e5ebcbe4
5
5
  SHA512:
6
- metadata.gz: dde0a94e68ed2c7ffec3b63a9e7ac6b3c32c86c67f65879dc33ea10a16208c1cf8180918b26ebcb84745ced85bfb96c1639b4a020fbda5135e070b73aea97773
7
- data.tar.gz: 52ae5c15f4dae06925f9c79b16071e2bbee70ecdfeed1e37cd18e33aa67c834b29cd82b1f69b3d99811d002e58eb4e60678be2e8d1f4a4ec951c50898394f02e
6
+ metadata.gz: 278c2f861d6a222a31d5f3f9b3bea27600fc587a804a27c46916270ef033e13edde802839657eee38484c18453b9095d09f75983c86b1eac2f208ca14a8676f7
7
+ data.tar.gz: 354d693d5f86494c4c1f94bcba338bbea1a3f4b12296c04c0332b5f3c258560e3c26ebf30c9b146212e34eb5de1bb96a44333257c8ab3633343947cf20d7e860
data/README.md CHANGED
@@ -18,12 +18,18 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
+ This gem supports Estonian and Latvian identity codes. Just specify `EE` or `LV` class accordingly (`IdentityCode::EE` or `IdentityCode::LV`)
22
+
23
+ *NB*: Latvian identity codes don't have sex support
24
+
21
25
  ```ruby
22
26
  > require 'identity_code'
23
- > code = IdentityCode::Isikukood.new('38312203720')
27
+ > code = IdentityCode::EE.new('38312203720')
24
28
  > code.valid?
25
29
  # or
26
- > IdentityCode::Isikukood.valid?('38312203720')
30
+ > IdentityCode::EE.valid?('38312203720')
31
+ => true
32
+ > IdentityCode::LV.valid?('20128315289')
27
33
  => true
28
34
  > code.sex
29
35
  => 'M'
@@ -32,10 +38,12 @@ Or install it yourself as:
32
38
  > code.age
33
39
  => 31
34
40
  # Generate random valid identity code
35
- > IdentityCode::Isikukood.generate
41
+ > IdentityCode::EE.generate
36
42
  => '37504163700'
37
- > IdentityCode::Isikukood.generate(sex: 'M', year: 1983, month: 12, day: 20)
43
+ > IdentityCode::EE.generate(sex: 'M', year: 1983, month: 12, day: 20)
38
44
  => '38312209528'
45
+ > IdentityCode::LV.generate(year: 1983, month: 12, day: 20, separator: true)
46
+ => '201283-15289'
39
47
  ```
40
48
 
41
49
  ## Development
data/identitycode.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Artem Pakk']
10
10
  spec.email = ['apakk@me.com']
11
11
 
12
- spec.summary = %q{Ruby gem to generate and validate Estonian identity codes}
13
- spec.description = %q{Ruby gem to generate and validate Estonian identity codes}
12
+ spec.summary = %q{Ruby gem to generate and validate Estonian and Latvian identity codes}
13
+ spec.description = %q{Ruby gem to generate and validate Estonian and Latvian identity codes}
14
14
  spec.homepage = 'https://github.com/defeed/identitycode'
15
15
  spec.license = "MIT"
16
16
 
@@ -0,0 +1,106 @@
1
+ require 'date'
2
+
3
+ module IdentityCode
4
+ class EE
5
+ HOSPITALS = [
6
+ '00', # Kuressaare Haigla (järjekorranumbrid 001 kuni 020)
7
+ '01', # Tartu Ülikooli Naistekliinik, Tartumaa, Tartu (011...019)
8
+ '02', # Ida-Tallinna Keskhaigla, Hiiumaa, Keila, Rapla haigla (021...220)
9
+ '22', # Ida-Viru Keskhaigla (Kohtla-Järve, endine Jõhvi) (221...270)
10
+ '27', # Maarjamõisa Kliinikum (Tartu), Jõgeva Haigla (271...370)
11
+ '37', # Narva Haigla (371...420)
12
+ '42', # Pärnu Haigla (421...470)
13
+ '47', # Pelgulinna Sünnitusmaja (Tallinn), Haapsalu haigla (471...490)
14
+ '49', # Järvamaa Haigla (Paide) (491...520)
15
+ '52', # Rakvere, Tapa haigla (521...570)
16
+ '57', # Valga Haigla (571...600)
17
+ '60', # Viljandi Haigla (601...650)
18
+ '65', # Lõuna-Eesti Haigla (Võru), Pälva Haigla (651...710?)
19
+ '70', # All other hospitals
20
+ '95' # Foreigners who are born in Estonia
21
+ ]
22
+
23
+ def self.generate(opts = {})
24
+ first_digit = 0
25
+
26
+ sex = opts[:sex] || (rand.round == 0 ? :M : :F)
27
+ year = opts[:year] || rand(Date.today.year - 90..Date.today.year - 1)
28
+ year = rand(Date.today.year - 50..Date.today.year - 19) if opts[:safe_age]
29
+ month = opts[:month] || rand(1..12)
30
+ day = opts[:day] || rand(1..NUM_DAYS[month])
31
+
32
+ first_digit += 1 if (1800..1899).include?(year)
33
+ first_digit += 3 if (1900..1999).include?(year)
34
+ first_digit += 5 if year >= 2000
35
+ first_digit += 1 if sex.upcase.to_sym == :F
36
+
37
+ result = first_digit.to_s
38
+ result += "%02d" % year.to_s[2..3].to_i
39
+ result += "%02d" % month
40
+ result += "%02d" % day
41
+ result += HOSPITALS[(rand * HOSPITALS.size - 1).round]
42
+ result += rand(0..9).to_s
43
+ result += new(result).control_code.to_s
44
+ end
45
+
46
+ def self.valid?(code)
47
+ new(code).valid?
48
+ end
49
+
50
+ def initialize(code)
51
+ @code = code.to_s
52
+ end
53
+
54
+ def valid?
55
+ @code.length == 11 &&
56
+ @code[10].chr.to_i == control_code
57
+ end
58
+
59
+ def birth_date
60
+ return unless valid?
61
+ year = century + @code[1..2].to_i
62
+ month = @code[3..4].to_i
63
+ day = @code[5..6].to_i
64
+ return unless Date.valid_date?(year, month, day)
65
+ Date.new(year, month, day)
66
+ end
67
+
68
+ def age
69
+ return unless valid?
70
+ now = Time.now.utc.to_date
71
+ now.year - (birth_date.year + IdentityCode::age_correction(birth_date))
72
+ end
73
+
74
+ def sex
75
+ return unless valid?
76
+ @code[0].to_i.odd? ? :M : :F
77
+ end
78
+
79
+ def control_code
80
+ scales1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]
81
+ checknum = scales1.each_with_index.map do |scale, i|
82
+ @code[i].chr.to_i * scale
83
+ end.inject(0, :+) % 11
84
+ return checknum unless checknum == 10
85
+
86
+ scales2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
87
+ checknum = scales2.each_with_index.map do |scale, i|
88
+ @code[i].chr.to_i * scale
89
+ end.inject(0, :+) % 11
90
+
91
+ checknum == 10 ? 0 : checknum
92
+ end
93
+
94
+ private
95
+
96
+ def century
97
+ case @code[0].chr.to_i
98
+ when 1..2 then 1800
99
+ when 3..4 then 1900
100
+ when 5..6 then 2000
101
+ else
102
+ 2100
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,83 @@
1
+ require 'date'
2
+
3
+ module IdentityCode
4
+ class LV
5
+ def initialize(code)
6
+ @code = code.to_s.gsub('-', '')
7
+ end
8
+
9
+ def self.generate(opts = {})
10
+ year = opts[:year] || rand(Date.today.year - 90..Date.today.year - 1)
11
+ year = rand(Date.today.year - 50..Date.today.year - 19) if opts[:safe_age]
12
+ month = opts[:month] || rand(1..12)
13
+ day = opts[:day] || rand(1..NUM_DAYS[month])
14
+
15
+ century_code = begin
16
+ case year
17
+ when 1800..1899 then 0
18
+ when 1900..1999 then 1
19
+ when 2000..2099 then 2
20
+ else
21
+ 9
22
+ end
23
+ end.to_s
24
+
25
+ result = "%02d" % day
26
+ result += "%02d" % month
27
+ result += "%02d" % year.to_s[2..3].to_i
28
+ result += '-' if opts[:separator]
29
+ result += century_code
30
+ result += "%03d" % rand(0..999).to_s
31
+ result += new(result).control_code.to_s
32
+ end
33
+
34
+ def self.valid?(code)
35
+ new(code).valid?
36
+ end
37
+
38
+ def valid?
39
+ @code.length == 11 &&
40
+ @code[10].chr.to_i == control_code
41
+ end
42
+
43
+ def birth_date
44
+ return unless valid?
45
+ year = century + @code[4..5].to_i
46
+ month = @code[2..3].to_i
47
+ day = @code[0..1].to_i
48
+ return unless Date.valid_date?(year, month, day)
49
+ Date.new(year, month, day)
50
+ end
51
+
52
+ def age
53
+ return unless valid?
54
+ now = Time.now.utc.to_date
55
+ now.year - (birth_date.year + IdentityCode.age_correction(birth_date))
56
+ end
57
+
58
+ def control_code
59
+ array = @code.split('').map(&:to_i)
60
+ multipliers = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
61
+ hash = Hash[multipliers.zip(array)]
62
+
63
+ check = 0
64
+ hash.map do |k, v|
65
+ check += k * v
66
+ end
67
+
68
+ ((1 - check) % 11) % 10
69
+ end
70
+
71
+ private
72
+
73
+ def century
74
+ case @code[6].chr.to_i
75
+ when 0 then 1800
76
+ when 1 then 1900
77
+ when 2 then 2000
78
+ else
79
+ 2100
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,3 +1,3 @@
1
1
  module IdentityCode
2
- VERSION = '0.1.3'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/identity_code.rb CHANGED
@@ -1,129 +1,50 @@
1
1
  require 'identity_code/version'
2
- require 'date'
2
+ require 'identity_code/ee'
3
+ require 'identity_code/lv'
3
4
 
4
5
  module IdentityCode
5
- class Isikukood
6
- HOSPITALS = [
7
- '00', # Kuressaare Haigla (järjekorranumbrid 001 kuni 020)
8
- '01', # Tartu Ülikooli Naistekliinik, Tartumaa, Tartu (011...019)
9
- '02', # Ida-Tallinna Keskhaigla, Hiiumaa, Keila, Rapla haigla (021...220)
10
- '22', # Ida-Viru Keskhaigla (Kohtla-Järve, endine Jõhvi) (221...270)
11
- '27', # Maarjamõisa Kliinikum (Tartu), Jõgeva Haigla (271...370)
12
- '37', # Narva Haigla (371...420)
13
- '42', # Pärnu Haigla (421...470)
14
- '47', # Pelgulinna Sünnitusmaja (Tallinn), Haapsalu haigla (471...490)
15
- '49', # Järvamaa Haigla (Paide) (491...520)
16
- '52', # Rakvere, Tapa haigla (521...570)
17
- '57', # Valga Haigla (571...600)
18
- '60', # Viljandi Haigla (601...650)
19
- '65', # Lõuna-Eesti Haigla (Võru), Pälva Haigla (651...710?)
20
- '70', # All other hospitals
21
- '95' # Foreigners who are born in Estonia
22
- ]
23
-
24
- NUM_DAYS = {
25
- 1 => 31,
26
- 2 => 28,
27
- 3 => 31,
28
- 4 => 30,
29
- 5 => 31,
30
- 6 => 30,
31
- 7 => 31,
32
- 8 => 31,
33
- 9 => 30,
34
- 10 => 31,
35
- 11 => 30,
36
- 12 => 31
37
- }
38
-
39
- def self.generate(opts = {})
40
- first_digit = 0
41
-
42
- sex = opts[:sex] || (rand.round == 0 ? 'M' : 'F')
43
- year = opts[:year] || rand(Date.today.year - 90..Date.today.year - 1)
44
- year = rand(Date.today.year - 50..Date.today.year - 19) if opts[:safe_age]
45
- month = opts[:month] || rand(1..12)
46
- day = opts[:day] || rand(1..NUM_DAYS[month])
47
-
48
- first_digit += 1 if (1800..1899).include?(year)
49
- first_digit += 3 if (1900..1999).include?(year)
50
- first_digit += 5 if year >= 2000
51
- first_digit += 1 if sex == 'F'
52
-
53
- result = first_digit.to_s
54
- result += "%02d" % year.to_s[2..3].to_i
55
- result += "%02d" % month
56
- result += "%02d" % day
57
- result += HOSPITALS[(rand * HOSPITALS.size - 1).round]
58
- result += rand(0..9).to_s
59
- result += new(result).control_code.to_s
60
- end
61
-
62
- def self.valid?(code)
63
- new(code).valid?
64
- end
65
-
66
- def initialize(code)
67
- @code = code.to_s
68
- end
69
-
70
- def valid?
71
- @code.length == 11 &&
72
- @code[10].chr.to_i == control_code
73
- end
74
-
75
- def birth_date
76
- return unless valid?
77
- year = century + @code[1..2].to_i
78
- month = @code[3..4].to_i
79
- day = @code[5..6].to_i
80
- return unless Date.valid_date?(year, month, day)
81
- Date.new(year, month, day)
82
- end
83
-
84
- def age
85
- return unless valid?
86
- now = Time.now.utc.to_date
87
- now.year - (birth_date.year + age_correction)
88
- end
89
-
90
- def sex
91
- return unless valid?
92
- @code[0].to_i.odd? ? 'M' : 'F'
93
- end
94
-
95
- def control_code
96
- scales1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]
97
- checknum = scales1.each_with_index.map do |scale, i|
98
- @code[i].chr.to_i * scale
99
- end.inject(0, :+) % 11
100
- return checknum unless checknum == 10
101
-
102
- scales2 = [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
103
- checknum = scales2.each_with_index.map do |scale, i|
104
- @code[i].chr.to_i * scale
105
- end.inject(0, :+) % 11
6
+ NUM_DAYS = {
7
+ 1 => 31,
8
+ 2 => 28,
9
+ 3 => 31,
10
+ 4 => 30,
11
+ 5 => 31,
12
+ 6 => 30,
13
+ 7 => 31,
14
+ 8 => 31,
15
+ 9 => 30,
16
+ 10 => 31,
17
+ 11 => 30,
18
+ 12 => 31
19
+ }.freeze
20
+
21
+ SUPPORTED_COUNTRY_CODES = %i(ee lv).freeze
22
+
23
+ def self.generate(opts = {})
24
+ country_code = opts.delete(:country)
25
+ raise 'Country param is missing or invalid (ee or lv)' unless begin
26
+ country_code &&
27
+ SUPPORTED_COUNTRY_CODES.include?(country_code.downcase.to_sym)
28
+ end
29
+
30
+ Object.const_get("IdentityCode::#{country_code.upcase}").generate(opts)
31
+ end
106
32
 
107
- checknum == 10 ? 0 : checknum
33
+ def self.valid?(opts = {})
34
+ country_code = opts.delete(:country)
35
+ raise 'Country param is missing or invalid (ee or lv)' unless begin
36
+ country_code &&
37
+ SUPPORTED_COUNTRY_CODES.include?(country_code.downcase.to_sym)
108
38
  end
109
39
 
110
- private
111
-
112
- def age_correction
113
- now = Time.now.utc.to_date
114
- return 0 if now.month > birth_date.month
115
- return 0 if now.month == birth_date.month && now.day >= birth_date.day
116
- 1
117
- end
40
+ code = opts.delete(:code)
41
+ Object.const_get("IdentityCode::#{country_code.upcase}").valid?(code)
42
+ end
118
43
 
119
- def century
120
- case @code[0].chr.to_i
121
- when 1..2 then 1800
122
- when 3..4 then 1900
123
- when 5..6 then 2000
124
- else
125
- 2100
126
- end
127
- end
44
+ def self.age_correction(birth_date)
45
+ now = Time.now.utc.to_date
46
+ return 0 if now.month > birth_date.month
47
+ return 0 if now.month == birth_date.month && now.day >= birth_date.day
48
+ 1
128
49
  end
129
50
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: identitycode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Pakk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-19 00:00:00.000000000 Z
11
+ date: 2016-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
- description: Ruby gem to generate and validate Estonian identity codes
41
+ description: Ruby gem to generate and validate Estonian and Latvian identity codes
42
42
  email:
43
43
  - apakk@me.com
44
44
  executables: []
@@ -55,6 +55,8 @@ files:
55
55
  - bin/setup
56
56
  - identitycode.gemspec
57
57
  - lib/identity_code.rb
58
+ - lib/identity_code/ee.rb
59
+ - lib/identity_code/lv.rb
58
60
  - lib/identity_code/version.rb
59
61
  homepage: https://github.com/defeed/identitycode
60
62
  licenses:
@@ -76,8 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
78
  version: '0'
77
79
  requirements: []
78
80
  rubyforge_project:
79
- rubygems_version: 2.4.8
81
+ rubygems_version: 2.4.5.1
80
82
  signing_key:
81
83
  specification_version: 4
82
- summary: Ruby gem to generate and validate Estonian identity codes
84
+ summary: Ruby gem to generate and validate Estonian and Latvian identity codes
83
85
  test_files: []