taiwanese_id_validator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d7bc7d3ead210e4f0ada15a66981b4b70fe58139
4
+ data.tar.gz: 0041fce3f39879b1cfd0bfe11fe3a3f6fdd18710
5
+ SHA512:
6
+ metadata.gz: 15c3820088f346a230802ab6723407f3ee0fa177e4af31fea9af491ed8c5ce717cacb3cc09192903713c12227530df6a90f34089003bcf9f5129a32f6e00dde5
7
+ data.tar.gz: 47115e8e91c29985274f7d8a475e8aa426c9e52c11661a94cdd1866c76dbd57278f2d78fa575a99a727763559f543eea5240ba6ecc18c48de70beb46f50a819b
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .DS_Store
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.3
5
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Wayne Chu
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Taiwanese Id Validator for Ruby on Rails
2
+
3
+ [![Build Status](https://travis-ci.org/wayne5540/taiwanese_id_validator.svg?branch=master)](https://travis-ci.org/wayne5540/taiwanese_id_validator)
4
+
5
+ 台灣身分證字號 驗證&產生 的 Gem
6
+
7
+ ## Features
8
+
9
+ * Rails model 內驗證 (Rails 3+/4)
10
+ * Rails model 外驗證
11
+ * 產生符合格式的身分證字號,可選擇男女
12
+
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'taiwanese_id_validator'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install taiwanese_id_validator
27
+
28
+ ## Usage
29
+
30
+ ### Rails Model Validation
31
+
32
+ #### 基本使用
33
+
34
+ ```ruby
35
+ class User < ActiveRecord::Base
36
+ validates :twid, taiwanese_id: true
37
+ end
38
+ ```
39
+
40
+ #### Options
41
+
42
+ * `allow_nil` or `allow_blank`
43
+
44
+ ```ruby
45
+ class User < ActiveRecord::Base
46
+ validates :twid, taiwanese_id: { allow_nil: true }
47
+ end
48
+ ```
49
+
50
+ * Case sensitive, default is true
51
+
52
+ ```ruby
53
+ class User < ActiveRecord::Base
54
+ validates :twid, taiwanese_id: { case_sensitive: false }
55
+ end
56
+ ```
57
+
58
+
59
+ ### Validation outside the model
60
+
61
+ #### 驗證身分證字號
62
+
63
+ ```ruby
64
+ TwidValidator.valid?('A123456789') #=> true
65
+ ```
66
+
67
+ ```ruby
68
+ TwidValidator.valid?('A123456777') #=> false
69
+ ```
70
+
71
+ #### 產生假身分證字號
72
+
73
+ ```ruby
74
+ TwidGenerator.generate #=> 隨機產生身分證字號
75
+ ```
76
+
77
+ ```ruby
78
+ TwidGenerator.generate("male") #=> 男性的身分證字號
79
+ ```
80
+
81
+ ```ruby
82
+ TwidGenerator.generate("female") #=> 女性的身分證字號
83
+ ```
84
+
85
+ ## Others
86
+
87
+ [公式](https://zh.wikipedia.org/wiki/%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E5%9C%8B%E6%B0%91%E8%BA%AB%E5%88%86%E8%AD%89)
88
+
89
+
90
+ ## Contributing
91
+
92
+ 1. Fork it ( https://github.com/[my-github-username]/taiwanese_id_validator/fork )
93
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
94
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
95
+ 4. Push to the branch (`git push origin my-new-feature`)
96
+ 5. Create a new Pull Request
97
+
98
+
99
+ ## LICENSE
100
+
101
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.rspec_opts = %w(--format documentation --colour)
8
+ end
9
+
10
+ task :default => 'spec'
@@ -0,0 +1,21 @@
1
+ require "taiwanese_id_validator/twid_validator"
2
+
3
+ class TaiwaneseIdValidator < ActiveModel::EachValidator
4
+ def validate_each(record, attribute, value)
5
+ return if skip_check?
6
+
7
+ unless TwidValidator.valid?(value, case_sensitive?)
8
+ record.errors[attribute] << (options[:message] || "is not an valid ID")
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def skip_check?
15
+ options[:allow_nil].present? || options[:allow_blank].present?
16
+ end
17
+
18
+ def case_sensitive?
19
+ options[:case_sensitive].nil? ? true : options[:case_sensitive]
20
+ end
21
+ end
@@ -0,0 +1,63 @@
1
+ require 'taiwanese_id_validator/twid_mapping'
2
+
3
+ module TwidGenerator
4
+ # TODO: Refactor this method first!
5
+ def self.generate(gender = nil)
6
+ sum = 0
7
+ twid = ""
8
+
9
+ first_letter = TwidMapping::TWID_LETTER.keys.sample
10
+
11
+ sum += TwidMapping::TWID_LETTER[first_letter][0] * TwidMapping::MULTIPLIER[0]
12
+ sum += TwidMapping::TWID_LETTER[first_letter][1] * TwidMapping::MULTIPLIER[1]
13
+
14
+
15
+ twid += first_letter.to_s
16
+
17
+ case gender
18
+ when "male"
19
+ second_letter = 1
20
+ when "female"
21
+ second_letter = 2
22
+ else
23
+ second_letter = [1, 2].sample
24
+ end
25
+ sum += second_letter * TwidMapping::MULTIPLIER[2]
26
+ twid += second_letter.to_s
27
+
28
+ 6.times do |i|
29
+ letter = Random.rand(1..9)
30
+ sum += letter * TwidMapping::MULTIPLIER[i + 3]
31
+ twid += letter.to_s
32
+ end
33
+
34
+ if sum % 10 == 0
35
+ last_two_letter = Random.rand(1..9)
36
+ sum += last_two_letter
37
+ twid += last_two_letter.to_s
38
+
39
+ last_letter = 10 - last_two_letter
40
+ sum += last_letter
41
+ twid += last_letter.to_s
42
+ elsif sum % 10 == 9
43
+ last_two_letter = Random.rand(2..10)
44
+ sum += last_two_letter
45
+ twid += last_two_letter.to_s
46
+
47
+ last_letter = 11 - last_two_letter
48
+ sum += last_letter
49
+ twid += last_letter.to_s
50
+ else
51
+ max_range = 10 - (sum % 10) - 1
52
+ last_two_letter = Random.rand(1..max_range)
53
+ sum += last_two_letter
54
+ twid += last_two_letter.to_s
55
+
56
+ last_letter = max_range + 1 - last_two_letter
57
+ sum += last_letter
58
+ twid += last_letter.to_s
59
+ end
60
+
61
+ return twid
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ module TwidMapping
2
+ TWID_LETTER = {
3
+ "A" => [1, 0], "B" => [1, 1], "C" => [1, 2], "D" => [1, 3],
4
+ "E" => [1, 4], "F" => [1, 5], "G" => [1, 6], "H" => [1, 7],
5
+ "I" => [3, 4], "J" => [1, 8], "K" => [1, 9], "L" => [2, 0],
6
+ "M" => [2, 1], "N" => [2, 2], "O" => [3, 5], "P" => [2, 3],
7
+ "Q" => [2, 4], "R" => [2, 5], "S" => [2, 6], "T" => [2, 7],
8
+ "U" => [2, 8], "V" => [2, 9], "W" => [3, 2], "X" => [3, 0],
9
+ "Y" => [3, 1], "Z" => [3, 3]
10
+ }
11
+
12
+ MULTIPLIER = [1,9,8,7,6,5,4,3,2,1,1].freeze
13
+ end
@@ -0,0 +1,28 @@
1
+ require 'taiwanese_id_validator/twid_mapping'
2
+
3
+ module TwidValidator
4
+ def self.valid?(twid, case_sensitive = true)
5
+ twid = twid.upcase unless case_sensitive
6
+
7
+ return false if twid.length != 10
8
+ return false if !( /[A-Z](1|2)\d{8}\z/ =~ twid )
9
+
10
+ characters = twid.chars
11
+ digits = TwidMapping::TWID_LETTER[characters.shift] + characters.map(&:to_i)
12
+
13
+ weighted_sum = calculate_weighted_sum(digits)
14
+
15
+ return weighted_sum % 10 == 0
16
+ end
17
+
18
+ private
19
+
20
+ def self.calculate_weighted_sum(digits)
21
+ sum = 0
22
+ 11.times do |i|
23
+ m = digits[i] * TwidMapping::MULTIPLIER[i]
24
+ sum += m
25
+ end
26
+ sum
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'active_model'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+
8
+ require 'taiwanese_id_validator'
9
+
10
+ class TestModel
11
+ include ActiveModel::Validations
12
+
13
+ def initialize(attributes = {})
14
+ @attributes = attributes
15
+ end
16
+
17
+ def read_attribute_for_validation(key)
18
+ @attributes[key]
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require "taiwanese_id_validator/twid_generator"
3
+
4
+ describe TwidGenerator do
5
+ describe "#generate" do
6
+ it "always generate valid ID" do
7
+ fake_ids = 1000.times.map do
8
+ TwidValidator.valid?(TwidGenerator.generate)
9
+ end
10
+
11
+ expect(fake_ids.all?{true}).to be true
12
+ end
13
+
14
+ describe "is able to fake male or female ID" do
15
+ context "when generate female ID" do
16
+ it "first number charactor should be 2" do
17
+ fake_id = TwidGenerator.generate("female")
18
+ first_number = fake_id.split(//)[1]
19
+
20
+ expect(first_number).to eq("2")
21
+ end
22
+ end
23
+
24
+ context "when generate male ID" do
25
+ it "first number charactor should be 1" do
26
+ fake_id = TwidGenerator.generate("male")
27
+ first_number = fake_id.split(//)[1]
28
+
29
+ expect(first_number).to eq("1")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe TwidValidator do
4
+
5
+ describe "#valid?" do
6
+ context "when id not valid" do
7
+ it "returns false if id too short" do
8
+ expect( TwidValidator.valid?("E123") ).to be false
9
+ end
10
+
11
+ it "returns false if id too long" do
12
+ expect( TwidValidator.valid?("Y144713411000") ).to be false
13
+ end
14
+
15
+ it "returns false if id calculation is wrong" do
16
+ expect( TwidValidator.valid?("Y144713412") ).to be false
17
+ end
18
+
19
+ it "returns false if format is wrong" do
20
+ expect( TwidValidator.valid?("YAC4713412") ).to be false
21
+ end
22
+ end
23
+
24
+ context "when id is valid" do
25
+ let(:id) { "Y144713411" }
26
+
27
+ it "returns true" do
28
+ expect( TwidValidator.valid?(id) ).to be true
29
+ end
30
+ end
31
+
32
+ pending "case sensative"
33
+ end
34
+
35
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ class TestUser < TestModel
4
+ validates :twid, taiwanese_id: true
5
+ end
6
+
7
+ class TestUserAllowsNil < TestModel
8
+ validates :twid, taiwanese_id: { allow_nil: true }
9
+ end
10
+
11
+ class TestUserNoCaseSensitive < TestModel
12
+ validates :twid, taiwanese_id: { case_sensitive: false }
13
+ end
14
+
15
+ describe TaiwaneseIdValidator do
16
+ describe "validation" do
17
+ context "given the valid IDs" do
18
+ [
19
+ "Y144713411"
20
+ ].each do |twid|
21
+ it "#{twid} should be valid" do
22
+ expect(TestUser.new(twid: twid)).to be_valid
23
+ end
24
+
25
+ it "#{twid} should be valid" do
26
+ expect(TestUserAllowsNil.new(twid: nil)).to be_valid
27
+ end
28
+
29
+ it "#{twid} should be valid" do
30
+ expect(TestUserNoCaseSensitive.new(twid: twid.downcase)).to be_valid
31
+ end
32
+ end
33
+ end
34
+
35
+ context "given the invalid IDs" do
36
+ [
37
+ "Y144",
38
+ "Y1447134111",
39
+ "Ya44713411",
40
+ "Y144713410",
41
+ "y144713411"
42
+ ].each do |twid|
43
+ it "#{twid} should be valid" do
44
+ expect(TestUser.new(twid: twid)).not_to be_valid
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "taiwanese_id_validator"
3
+ spec.version = "0.0.1"
4
+ spec.authors = ["Wayne Chu"]
5
+ spec.email = ["wayne.5540@gmail.com"]
6
+ spec.summary = "Taiwanese Id Validator."
7
+ spec.description = "Taiwanese Id Validator"
8
+ spec.homepage = ""
9
+ spec.license = "MIT"
10
+ spec.files = `git ls-files`.split("\n")
11
+ spec.test_files = `git ls-files -- {spec}/*`.split("\n")
12
+ spec.require_paths = ["lib"]
13
+
14
+
15
+ spec.add_dependency "activemodel"
16
+
17
+ spec.add_development_dependency "bundler", "~> 1.6"
18
+ spec.add_development_dependency "rake"
19
+ spec.add_development_dependency "rspec"
20
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taiwanese_id_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Wayne Chu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Taiwanese Id Validator
70
+ email:
71
+ - wayne.5540@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/taiwanese_id_validator.rb
83
+ - lib/taiwanese_id_validator/twid_generator.rb
84
+ - lib/taiwanese_id_validator/twid_mapping.rb
85
+ - lib/taiwanese_id_validator/twid_validator.rb
86
+ - spec/spec_helper.rb
87
+ - spec/taiwanese_id_validator/twid_generator_spec.rb
88
+ - spec/taiwanese_id_validator/twid_validator_spec.rb
89
+ - spec/taiwanese_id_validator_spec.rb
90
+ - taiwanese_id_validator.gemspec
91
+ homepage: ''
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.2.2
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Taiwanese Id Validator.
115
+ test_files: []