taiwanese_id_validator 0.0.1 → 0.0.2
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.
- checksums.yaml +5 -5
- data/CHANGELOG +11 -0
- data/README.md +20 -2
- data/lib/international_id_validator/itid_mapping.rb +13 -0
- data/lib/international_id_validator/itid_validator.rb +29 -0
- data/lib/international_id_validator.rb +25 -0
- data/lib/taiwanese_id_validator.rb +1 -1
- data/spec/international_id_validator_spec.rb +71 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/taiwanese_id_validator/twid_validator_spec.rb +1 -4
- data/spec/taiwanese_id_validator_spec.rb +9 -9
- data/taiwanese_id_validator.gemspec +4 -4
- metadata +16 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 138804708933184e1ad20325ad662f9fb26a6b6841f7ebbdc844319ab6f41245
|
|
4
|
+
data.tar.gz: 591d61b99e22b9ecc372fb0924686bbeb13a108da813cb14d730cdf22c008a8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 026a849d7d4c4d8a605a1eb36a754ca09c249a6930930c67d1e5d4e695b3a89f2df3fe5eeed255423e1d7f0bc0126309b6513d064fbe683d1a96c3b4bcd3855c
|
|
7
|
+
data.tar.gz: c3153324521c9baa73603483925c5f43d5dbd7464992cadd7995d0b3c5294da1c57363b6c675884f0aef125d03231f154ba9593542a4ed351b8f5ebfe2a545a9
|
data/CHANGELOG
ADDED
data/README.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
* Rails model 內驗證 (Rails 3+/4)
|
|
10
10
|
* Rails model 外驗證
|
|
11
|
+
* 新式統一證號驗證
|
|
11
12
|
* 產生符合格式的身分證字號,可選擇男女
|
|
12
13
|
|
|
13
14
|
|
|
@@ -70,10 +71,16 @@ TwidValidator.valid?('A123456777') #=> false
|
|
|
70
71
|
|
|
71
72
|
#### 產生假身分證字號
|
|
72
73
|
|
|
74
|
+
Generator 是沒有被自動 require 的,所以要使用前要先 require:
|
|
75
|
+
|
|
73
76
|
```ruby
|
|
77
|
+
require 'taiwanese_id_validator/twid_generator'
|
|
78
|
+
|
|
74
79
|
TwidGenerator.generate #=> 隨機產生身分證字號
|
|
75
80
|
```
|
|
76
81
|
|
|
82
|
+
可以指定要產生男性或是女性的身分證字號
|
|
83
|
+
|
|
77
84
|
```ruby
|
|
78
85
|
TwidGenerator.generate("male") #=> 男性的身分證字號
|
|
79
86
|
```
|
|
@@ -82,9 +89,20 @@ TwidGenerator.generate("male") #=> 男性的身分證字號
|
|
|
82
89
|
TwidGenerator.generate("female") #=> 女性的身分證字號
|
|
83
90
|
```
|
|
84
91
|
|
|
92
|
+
#### 驗證統一證號
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
ItidValidator.valid?('A800000014') #=> true
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```ruby
|
|
99
|
+
ItidValidator.valid?('A800000015') #=> false
|
|
100
|
+
```
|
|
101
|
+
|
|
85
102
|
## Others
|
|
86
103
|
|
|
87
|
-
[
|
|
104
|
+
[身分證公式](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)
|
|
105
|
+
[新式統一證號](http://www.registration.fcu.edu.tw/wSite/public/Attachment/f1582594331972.pdf)
|
|
88
106
|
|
|
89
107
|
|
|
90
108
|
## Contributing
|
|
@@ -98,4 +116,4 @@ TwidGenerator.generate("female") #=> 女性的身分證字號
|
|
|
98
116
|
|
|
99
117
|
## LICENSE
|
|
100
118
|
|
|
101
|
-
This project rocks and uses MIT-LICENSE.
|
|
119
|
+
This project rocks and uses MIT-LICENSE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ItidMapping
|
|
2
|
+
ITID_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].freeze
|
|
13
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'international_id_validator/itid_mapping'
|
|
2
|
+
|
|
3
|
+
module ItidValidator
|
|
4
|
+
def self.valid?(itid, case_sensitive = true, allow_old = false)
|
|
5
|
+
itid = itid.upcase unless case_sensitive
|
|
6
|
+
|
|
7
|
+
return false if itid.length != 10
|
|
8
|
+
return true if allow_old && itid.match?(/\A[A-Z][ABCD]\d{8}\z/)
|
|
9
|
+
return false unless itid.match?(/[A-Z](8|9)\d{8}\z/)
|
|
10
|
+
|
|
11
|
+
characters = itid.chars
|
|
12
|
+
digits = ItidMapping::ITID_LETTER[characters.shift] + characters.map(&:to_i)
|
|
13
|
+
|
|
14
|
+
checked_num = calculate_checked_num(digits)
|
|
15
|
+
|
|
16
|
+
return checked_num == digits.last
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def self.calculate_checked_num(digits)
|
|
22
|
+
sum = 0
|
|
23
|
+
10.times do |i|
|
|
24
|
+
m = digits[i] * ItidMapping::MULTIPLIER[i]
|
|
25
|
+
sum += (m % 10)
|
|
26
|
+
end
|
|
27
|
+
10 - (sum % 10)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "international_id_validator/itid_validator"
|
|
2
|
+
|
|
3
|
+
class InternationalIdValidator < ActiveModel::EachValidator
|
|
4
|
+
def validate_each(record, attribute, value)
|
|
5
|
+
return if skip_check?
|
|
6
|
+
|
|
7
|
+
unless ItidValidator.valid?(value, case_sensitive?, allow_old?)
|
|
8
|
+
record.errors.add(attribute, (options[:message] || "is not a 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
|
+
|
|
22
|
+
def allow_old?
|
|
23
|
+
options[:allow_old].nil? ? false : options[:allow_old]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -5,7 +5,7 @@ class TaiwaneseIdValidator < ActiveModel::EachValidator
|
|
|
5
5
|
return if skip_check?
|
|
6
6
|
|
|
7
7
|
unless TwidValidator.valid?(value, case_sensitive?)
|
|
8
|
-
record.errors
|
|
8
|
+
record.errors.add(attribute, (options[:message] || "is not a valid ID"))
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class ItTestUser < TestModel
|
|
4
|
+
validates :itid, international_id: true
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class ItTestUserAllowsNil < TestModel
|
|
8
|
+
validates :itid, international_id: { allow_nil: true }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ItTestUserNoCaseSensitive < TestModel
|
|
12
|
+
validates :itid, international_id: { case_sensitive: false }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class ItTestUserAllowOld < TestModel
|
|
16
|
+
validates :itid, international_id: { allow_old: true }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe InternationalIdValidator do
|
|
20
|
+
describe "validation" do
|
|
21
|
+
context "given the valid new IDs" do
|
|
22
|
+
[
|
|
23
|
+
"A800000014"
|
|
24
|
+
].each do |itid|
|
|
25
|
+
it "#{itid} should be valid" do
|
|
26
|
+
expect(ItTestUser.new(itid: itid)).to be_valid
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "#{itid} should be valid" do
|
|
30
|
+
expect(ItTestUserAllowsNil.new(itid: nil)).to be_valid
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "#{itid} should be valid" do
|
|
34
|
+
expect(ItTestUserNoCaseSensitive.new(itid: itid.downcase)).to be_valid
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "#{itid} should be valid" do
|
|
38
|
+
expect(ItTestUserNoCaseSensitive.new(itid: itid.downcase)).to be_valid
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "given the valid old IDs" do
|
|
44
|
+
[
|
|
45
|
+
"AD00000016"
|
|
46
|
+
].each do |itid|
|
|
47
|
+
it "#{itid} should not be valid" do
|
|
48
|
+
expect(ItTestUser.new(itid: itid)).not_to be_valid
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "#{itid} should be valid" do
|
|
52
|
+
expect(ItTestUserAllowOld.new(itid: itid)).to be_valid
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "given the invalid IDs" do
|
|
58
|
+
[
|
|
59
|
+
"A8000014",
|
|
60
|
+
"A80000001411",
|
|
61
|
+
"Aa00000014",
|
|
62
|
+
"A800000015",
|
|
63
|
+
"a800000014"
|
|
64
|
+
].each do |itid|
|
|
65
|
+
it "#{itid} should not be valid" do
|
|
66
|
+
expect(ItTestUser.new(itid: itid)).not_to be_valid
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -6,6 +6,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
|
6
6
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
7
7
|
|
|
8
8
|
require 'taiwanese_id_validator'
|
|
9
|
+
require 'international_id_validator'
|
|
9
10
|
|
|
10
11
|
class TestModel
|
|
11
12
|
include ActiveModel::Validations
|
|
@@ -17,4 +18,4 @@ class TestModel
|
|
|
17
18
|
def read_attribute_for_validation(key)
|
|
18
19
|
@attributes[key]
|
|
19
20
|
end
|
|
20
|
-
end
|
|
21
|
+
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
class
|
|
3
|
+
class TwTestUser < TestModel
|
|
4
4
|
validates :twid, taiwanese_id: true
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
class
|
|
7
|
+
class TwTestUserAllowsNil < TestModel
|
|
8
8
|
validates :twid, taiwanese_id: { allow_nil: true }
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class TwTestUserNoCaseSensitive < TestModel
|
|
12
12
|
validates :twid, taiwanese_id: { case_sensitive: false }
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -19,15 +19,15 @@ describe TaiwaneseIdValidator do
|
|
|
19
19
|
"Y144713411"
|
|
20
20
|
].each do |twid|
|
|
21
21
|
it "#{twid} should be valid" do
|
|
22
|
-
expect(
|
|
22
|
+
expect(TwTestUser.new(twid: twid)).to be_valid
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it "#{twid} should be valid" do
|
|
26
|
-
expect(
|
|
26
|
+
expect(TwTestUserAllowsNil.new(twid: nil)).to be_valid
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "#{twid} should be valid" do
|
|
30
|
-
expect(
|
|
30
|
+
expect(TwTestUserNoCaseSensitive.new(twid: twid.downcase)).to be_valid
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -40,10 +40,10 @@ describe TaiwaneseIdValidator do
|
|
|
40
40
|
"Y144713410",
|
|
41
41
|
"y144713411"
|
|
42
42
|
].each do |twid|
|
|
43
|
-
it "#{twid} should be valid" do
|
|
44
|
-
expect(
|
|
43
|
+
it "#{twid} should not be valid" do
|
|
44
|
+
expect(TwTestUser.new(twid: twid)).not_to be_valid
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
end
|
|
49
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Gem::Specification.new do |spec|
|
|
2
2
|
spec.name = "taiwanese_id_validator"
|
|
3
|
-
spec.version = "0.0.
|
|
3
|
+
spec.version = "0.0.2"
|
|
4
4
|
spec.authors = ["Wayne Chu"]
|
|
5
5
|
spec.email = ["wayne.5540@gmail.com"]
|
|
6
6
|
spec.summary = "Taiwanese Id Validator."
|
|
7
7
|
spec.description = "Taiwanese Id Validator"
|
|
8
|
-
spec.homepage = ""
|
|
8
|
+
spec.homepage = "https://github.com/wayne5540/taiwanese_id_validator"
|
|
9
9
|
spec.license = "MIT"
|
|
10
10
|
spec.files = `git ls-files`.split("\n")
|
|
11
11
|
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
|
|
15
15
|
spec.add_dependency "activemodel"
|
|
16
16
|
|
|
17
|
-
spec.add_development_dependency "bundler", "
|
|
17
|
+
spec.add_development_dependency "bundler", ">= 2.2.33"
|
|
18
18
|
spec.add_development_dependency "rake"
|
|
19
19
|
spec.add_development_dependency "rspec"
|
|
20
|
-
end
|
|
20
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: taiwanese_id_validator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wayne Chu
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-12-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -28,16 +28,16 @@ dependencies:
|
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 2.2.33
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 2.2.33
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -75,24 +75,29 @@ extra_rdoc_files: []
|
|
|
75
75
|
files:
|
|
76
76
|
- ".gitignore"
|
|
77
77
|
- ".travis.yml"
|
|
78
|
+
- CHANGELOG
|
|
78
79
|
- Gemfile
|
|
79
80
|
- LICENSE.txt
|
|
80
81
|
- README.md
|
|
81
82
|
- Rakefile
|
|
83
|
+
- lib/international_id_validator.rb
|
|
84
|
+
- lib/international_id_validator/itid_mapping.rb
|
|
85
|
+
- lib/international_id_validator/itid_validator.rb
|
|
82
86
|
- lib/taiwanese_id_validator.rb
|
|
83
87
|
- lib/taiwanese_id_validator/twid_generator.rb
|
|
84
88
|
- lib/taiwanese_id_validator/twid_mapping.rb
|
|
85
89
|
- lib/taiwanese_id_validator/twid_validator.rb
|
|
90
|
+
- spec/international_id_validator_spec.rb
|
|
86
91
|
- spec/spec_helper.rb
|
|
87
92
|
- spec/taiwanese_id_validator/twid_generator_spec.rb
|
|
88
93
|
- spec/taiwanese_id_validator/twid_validator_spec.rb
|
|
89
94
|
- spec/taiwanese_id_validator_spec.rb
|
|
90
95
|
- taiwanese_id_validator.gemspec
|
|
91
|
-
homepage:
|
|
96
|
+
homepage: https://github.com/wayne5540/taiwanese_id_validator
|
|
92
97
|
licenses:
|
|
93
98
|
- MIT
|
|
94
99
|
metadata: {}
|
|
95
|
-
post_install_message:
|
|
100
|
+
post_install_message:
|
|
96
101
|
rdoc_options: []
|
|
97
102
|
require_paths:
|
|
98
103
|
- lib
|
|
@@ -107,9 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
107
112
|
- !ruby/object:Gem::Version
|
|
108
113
|
version: '0'
|
|
109
114
|
requirements: []
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
signing_key:
|
|
115
|
+
rubygems_version: 3.1.6
|
|
116
|
+
signing_key:
|
|
113
117
|
specification_version: 4
|
|
114
118
|
summary: Taiwanese Id Validator.
|
|
115
119
|
test_files: []
|