personnummer 0.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of personnummer might be problematic. Click here for more details.

Files changed (6) hide show
  1. data/Changelog +5 -0
  2. data/LICENSE +18 -0
  3. data/README.markdown +14 -0
  4. data/demo.rb +21 -0
  5. data/lib/personnummer.rb +145 -0
  6. metadata +66 -0
@@ -0,0 +1,5 @@
1
+ 0.0.2 Released
2
+
3
+ 2008-08-07: Number argument can now be a Fixnum or String
4
+
5
+ 0.0.1 Released
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2008 Peter Hellberg
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # Personnummer
2
+
3
+ Personnummer is a ruby class that handles [Swedish personal identity number](http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden\)).
4
+
5
+ ### Getting started
6
+
7
+ Install from GitHub: <pre>$ gem install c7-personnummer -s http://gems.github.com</pre>
8
+
9
+ ### Example usage
10
+ <pre>&gt;&gt; p = Personnummer.new('830428-5912')
11
+ =&gt; #&lt;Personnummer:0x301128 @number="830428-5912", @age=25, @valid=true, @region="Skaraborgs l\303\244n",
12
+ @male=true, @born=#&lt;Date: 4890905/2,0,2299161&gt;&gt;
13
+ &gt;&gt; p.valid?
14
+ =&gt; true</pre>
data/demo.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Real world scripts would use:
2
+ # require 'rubygems'
3
+ # require 'personnummer'
4
+ #
5
+ # Instead of:
6
+ require 'lib/personnummer'
7
+
8
+ # Valid personnummer
9
+ p = Personnummer.new(8304285912)
10
+ designation = (p.male?) ? 'His' : 'Her'
11
+ puts "#{designation} control digit is: #{p.control_digit}"
12
+
13
+ if p.valid?
14
+ designation = (p.male?) ? 'He' : 'She'
15
+ puts "#{designation} was born in #{p.region} aproximately #{p.age} years ago" if p.region
16
+ end
17
+
18
+ # Incomplete personnummer
19
+ p = Personnummer.new('870312-594')
20
+ designation = (p.male?) ? 'His' : 'Her'
21
+ puts "#{designation} control digit is: #{p.control_digit}"
@@ -0,0 +1,145 @@
1
+ require 'date'
2
+
3
+ class Personnummer
4
+ # Public readonly attributes
5
+ attr_reader :age, :born, :region, :control_digit
6
+
7
+ def initialize(number)
8
+
9
+ @valid = false
10
+
11
+ # Store the initial number
12
+ @number = number.to_s
13
+
14
+ # Match the number
15
+ if @number.match(/(\d{2})(\d{2})(\d{2})([\-\+]{0,1})(\d{3})(\d{0,1})/)
16
+
17
+ # Calculate the control digit based on the birth date and serial number
18
+ @control_digit = luhn_algorithm("#{$~[1]}#{$~[2]}#{$~[3]}#{$~[5]}")
19
+
20
+ # Get the different parts of the number
21
+ year = $~[1].to_i
22
+ month = $~[2].to_i
23
+ day = $~[3].to_i
24
+ divider = $~[4]
25
+ serial = $~[5].to_i
26
+
27
+ # Set default divider if not present
28
+ divider ||= '-'
29
+
30
+ # Make the personnummer valid if the checksum is correct
31
+ @valid = true if @control_digit == $~[6].to_i && !$~[6].empty?
32
+
33
+ # Get the current date
34
+ today = Date.today
35
+
36
+ # Decide which century corresponds to the number
37
+ if year < (today.year-2000) && divider == '-'
38
+ century = 2000
39
+ elsif year < (today.year-2000) && divider == '+'
40
+ century = 1900
41
+ elsif divider == '+'
42
+ century = 1800
43
+ else
44
+ century = 1900
45
+ end
46
+
47
+ # Get the date the person was born
48
+ @born = Date.parse("#{century+year}-#{month}-#{day}")
49
+
50
+ # Get the region name
51
+ @region = region_name(serial)
52
+
53
+ # Naïve age calculation
54
+ @age = today.year - @born.year
55
+
56
+ # Check if the person is female based the serial (even == female)
57
+ @female = (serial % 2 == 0)
58
+ else
59
+ raise Exception.new, "The supplied personnummer is invalid"
60
+ end
61
+ end
62
+
63
+ def to_s
64
+ @number
65
+ end
66
+
67
+ def valid?
68
+ @valid
69
+ end
70
+
71
+ def male?
72
+ !@female
73
+ end
74
+
75
+ def female?
76
+ @female
77
+ end
78
+
79
+ private
80
+
81
+ def luhn_algorithm(number)
82
+ multiplications = []
83
+
84
+ number.split(//).each_with_index do |digit, i|
85
+ if i % 2 == 0
86
+ multiplications << digit.to_i*2
87
+ else
88
+ multiplications << digit.to_i
89
+ end
90
+ end
91
+
92
+ sum = 0
93
+ multiplications.each do |number|
94
+ number.to_s.each_byte do |character|
95
+ sum += character.chr.to_i
96
+ end
97
+ end
98
+
99
+ if sum % 10 == 0
100
+ control_digit = 0
101
+ else
102
+ control_digit = (sum / 10 + 1) * 10 - sum
103
+ end
104
+
105
+ control_digit
106
+ end
107
+
108
+ def region_name(code)
109
+
110
+ # Don't return a region name if the person was born after 1990
111
+ # (When the previous region code was changed to a serial number)
112
+ if @born.year > 1990
113
+ return ''
114
+ end
115
+
116
+ case code
117
+ when 000..139: 'Stockholms Län'
118
+ when 140..159: 'Uppsala län'
119
+ when 160..189: 'Södermanlands län'
120
+ when 190..239: 'Östergötlands län'
121
+ when 240..269: 'Jönköpings län'
122
+ when 270..289: 'Kronobergs län'
123
+ when 290..319: 'Kalmar län'
124
+ when 320..329: 'Gotlands län'
125
+ when 330..349: 'Blekinge län'
126
+ when 350..389: 'Kristianstads län'
127
+ when 390..459: 'Malmöhus län'
128
+ when 460..479: 'Hallands län'
129
+ when 480..549: 'Göteborgs och Bohus län'
130
+ when 550..589: 'Älvsborgs län'
131
+ when 590..619: 'Skaraborgs län'
132
+ when 620..159: 'Värmlands län'
133
+ when 650..659: 'Födda utomlands'
134
+ when 660..689: 'Örebro län'
135
+ when 690..709: 'Västmanlands län'
136
+ when 710..739: 'Kopparbergs län'
137
+ when 750..779: 'Gävleborgs län'
138
+ when 780..819: 'Västernorrlands län'
139
+ when 820..849: 'Jämtlands län'
140
+ when 850..889: 'Västerbottens län'
141
+ when 890..929: 'Norrbottens län'
142
+ when 930..999: 'Födda utomlands eller utländska medborgare födda i Sverige'
143
+ end
144
+ end
145
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: personnummer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Peter Hellberg
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2008-08-06 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Personnummer handles validation of Swedish personal identity numbers.
22
+ email: peter@c7.se
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - README.markdown
31
+ - Changelog
32
+ - LICENSE
33
+ - demo.rb
34
+ - lib/personnummer.rb
35
+ has_rdoc: true
36
+ homepage: http://c7.se/code/personnummer
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.6
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Personnummer handles validation of Swedish personal identity numbers.
65
+ test_files: []
66
+