romanianvalidators 0.1.2 → 0.1.4
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 +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +0 -2
- data/CHANGELOG.md +7 -0
- data/README.md +5 -5
- data/lib/active_model/validations/bic_validator.rb +9 -18
- data/lib/active_model/validations/cif_validator.rb +16 -19
- data/lib/active_model/validations/cnp_validator.rb +37 -42
- data/lib/active_model/validations/iban_validator.rb +21 -20
- data/lib/romanianvalidators.rb +11 -0
- data/romanianvalidators.gemspec +1 -1
- data/test/data/valid_ro_ibans.txt +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 106793ba3003fa1e423dccb482ddb68ebe40434f
|
4
|
+
data.tar.gz: 4bedcaa54fadc580cc94e94be67d926d3276042d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07c908f816f01e6b7da2b8b44cea6a50fd6ef90a85345014444841d390b9bb2c38dfb56f5f03c269e6083265224cb2557a61c17b1ebc42dd4173bdc011bdb473
|
7
|
+
data.tar.gz: eb59ae55e08cfbed0c1af5ab7278b4d72837dc08ca7023da6182706761b799c721fc669b2b21087005e78732e90489554752036ac6ddc19e1e38528bc5a430f4
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Romanian Validators [](https://travis-ci.org/mtarnovan/romanianvalidators)
|
1
|
+
# Romanian Validators [](https://travis-ci.org/mtarnovan/romanianvalidators) [](http://badge.fury.io/rb/romanianvalidators) [](https://codeclimate.com/github/mtarnovan/romanianvalidators)
|
2
2
|
|
3
|
-
ActiveModel validators for:
|
3
|
+
ActiveModel validators for:
|
4
4
|
|
5
5
|
* Cod Numeric Personal (CNP)
|
6
|
-
* Cod de identificare fiscală (CIF) and
|
6
|
+
* Cod de identificare fiscală (CIF) and
|
7
7
|
* IBAN (only Romanian format as published by Romanian National Bank).
|
8
8
|
* BIC
|
9
9
|
|
@@ -47,9 +47,9 @@ The algorithms for validation are found in the source code.
|
|
47
47
|
|
48
48
|
### TODO
|
49
49
|
|
50
|
-
* test more edge cases
|
50
|
+
* test more edge cases
|
51
51
|
* add javascript validation ?
|
52
52
|
|
53
53
|
### Copyright
|
54
54
|
|
55
|
-
Copyright (c) 2007-
|
55
|
+
Copyright (c) 2007-2013 Mihai Târnovan. MIT LICENSE. See LICENSE for details.
|
@@ -1,28 +1,19 @@
|
|
1
1
|
module ActiveModel
|
2
2
|
module Validations
|
3
|
-
|
4
3
|
class BicValidator < EachValidator
|
5
|
-
|
6
|
-
|
7
|
-
allow_nil = options.fetch(:allow_nil, false)
|
8
|
-
message = options.fetch(:message, nil)
|
9
|
-
record.errors.add_on_empty(attribute) if value.nil? && !allow_nil
|
10
|
-
record.errors.add_on_blank(attribute) if value.blank? && !allow_blank
|
11
|
-
record.errors.add(attribute, message) unless Bic.valid?(value)
|
12
|
-
end
|
4
|
+
|
5
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
13
6
|
|
14
7
|
# This is only a basic validation of a BIC
|
15
8
|
# http://www.swift.com/biconline/index.cfm?fuseaction=display_aboutbic
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
false
|
23
|
-
end
|
9
|
+
def valid?(bic)
|
10
|
+
country_codes = %w[AF AL DZ AS AD AO AI AG AR AM AW AU AT AZ BS BH BD BB BY BE BZ BJ BM BT BO BA BW BR BN BG BF BI KH CM CA CV KY CF TD CL CN CO KM CG CD CK CR CI HR CU CY CZ DK DJ DM DO EC EG SV GQ ER EE ET FK FO FJ FI FR GF PF GA GM GE DE GH GI GR GL GD GP GU GT GN GW GY HT VA HN HK HU IS IN ID IR IQ IE IL IT JM JP JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW MY MV ML MT MH MQ MR MU MX FM MD MC MN MS MA MZ MM NA NR NP NL AN NC NZ NI NE NG NU NF MP NO OM PK PW PA PG PY PE PH PN PL PT PR QA RE RO RU RW SH KN LC PM VC WS SM ST SA SN SC SL SG SK SI SB SO ZA ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TG TK TO TT TN TR TM TC TV UG UA AE GB US UY UZ VU VE VN VG VI WF EH YE ZM ZW]
|
11
|
+
return false unless bic.size == 8 || bic.size == 11 # length 8 or 11
|
12
|
+
return false unless (bic[0..3]=~(/[^A-Z]/)).nil? # first 4 must be letters only
|
13
|
+
return true if country_codes.include?(bic[4..5])
|
14
|
+
false
|
24
15
|
end
|
25
|
-
end
|
26
16
|
|
17
|
+
end
|
27
18
|
end
|
28
19
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
module ActiveModel
|
2
2
|
module Validations
|
3
|
-
|
4
3
|
class CifValidator < EachValidator
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
record.errors.add_on_blank(attribute) if value.blank? && !allow_blank
|
11
|
-
record.errors.add(attribute, message) unless Cif.valid?(value)
|
12
|
-
end
|
4
|
+
|
5
|
+
# reversed test key (753217532)
|
6
|
+
TEST_KEY = "235712357".freeze
|
7
|
+
|
8
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
13
9
|
|
14
10
|
# Algoritmul de validare al unui cod CUI
|
15
11
|
# Pas preliminar: Se testeaza daca codul respecta formatul unui cod CUI. Adica lungimea maxima sa fie de 10 cifre si sa contina doar caractere numerice.
|
@@ -17,17 +13,18 @@ module ActiveModel
|
|
17
13
|
# Pas 2: Se ignora prima cifra din codul CUI inversat (aceasta este cifra de control) si se inmulteste fiecare cifra cu cifra corespunzatoare din cheia de testare inversata.
|
18
14
|
# Pas 3: Se aduna toate produsele obtinute. Suma rezultata se inmulteste cu 10 si apoi se afla restul impartirii la 11.
|
19
15
|
# Pas 4: Pentru un CUI valid cifra obtinuta, in urma operatiei MODULO 11, va trebui sa corespunda cu cifra de control a codului CUI initial .
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
return false unless (cif=~(/[^0-9]/)).nil?
|
25
|
-
rk = "235712357".freeze # reversed test key (753217532)
|
26
|
-
rc = cif.reverse.freeze
|
27
|
-
(1..(cif.size - 1)).inject(0) {|sum, n| sum += rk[n-1].chr.to_i * rc[n].chr.to_i} * 10 % 11 % 10 == rc[0].chr.to_i
|
28
|
-
end
|
16
|
+
def valid?(cif)
|
17
|
+
return false unless well_formed?(cif)
|
18
|
+
rc = cif.reverse.freeze
|
19
|
+
(1..(cif.size - 1)).inject(0) {|sum, n| sum += TEST_KEY[n-1].chr.to_i * rc[n].chr.to_i} * 10 % 11 % 10 == rc[0].chr.to_i
|
29
20
|
end
|
30
|
-
end
|
31
21
|
|
22
|
+
private
|
23
|
+
|
24
|
+
def well_formed?(cif)
|
25
|
+
cif.present? && (2..10).include?(cif.size) && (cif=~(/[^0-9]/)).nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
32
29
|
end
|
33
30
|
end
|
@@ -1,55 +1,50 @@
|
|
1
1
|
module ActiveModel
|
2
2
|
module Validations
|
3
|
-
|
4
3
|
class CnpValidator < EachValidator
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
record.errors.add_on_empty(attribute) if value.nil? && !allow_nil
|
10
|
-
record.errors.add_on_blank(attribute) if value.blank? && !allow_blank
|
11
|
-
record.errors.add(attribute, message) unless Cnp.valid?(value)
|
12
|
-
end
|
4
|
+
|
5
|
+
TEST_KEY = "279146358279"
|
6
|
+
|
7
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
13
8
|
|
14
9
|
# Algoritm de validare CNP
|
15
|
-
# Pas preliminar: Se testeaza daca codul respecta formatul unui cod CNP.
|
16
|
-
# Adica prima cifra sa fie cuprinsa in intervalul 1 - 6 sau sa fie 9 pentru straini.
|
10
|
+
# Pas preliminar: Se testeaza daca codul respecta formatul unui cod CNP.
|
11
|
+
# Adica prima cifra sa fie cuprinsa in intervalul 1 - 6 sau sa fie 9 pentru straini.
|
17
12
|
# Urmatoarele sase cifre trebuie sa constituie o data calendaristica valida in formatul AALLZZ.
|
18
13
|
#
|
19
|
-
# Pas 1:
|
20
|
-
# Se foloseste cheia de testare "279146358279". Primele douasprezece cifre se inmultesc pe rand de la
|
14
|
+
# Pas 1:
|
15
|
+
# Se foloseste cheia de testare "279146358279". Primele douasprezece cifre se inmultesc pe rand de la
|
21
16
|
# stanga spre dreapta cu cifra corespunzatoare din cheia de testare.
|
22
17
|
#
|
23
|
-
# Pas 2: Cele douasprezece produse obtinute se aduna si suma obtinuta se imparte la 11. Restul impartirii
|
24
|
-
# reprezinta cifra de control. Pentru un CNP valid acest rest va trebui sa coincida cu cifra de pe
|
25
|
-
# pozitia treisprezece din CNP-ul initial.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
begin
|
31
|
-
year = case
|
32
|
-
when
|
33
|
-
cnp[0].chr == "1" || cnp[0].chr == "2" then "19"
|
34
|
-
when
|
35
|
-
cnp[0].chr == "3" || cnp[0].chr == "4" then "18"
|
36
|
-
when
|
37
|
-
cnp[0].chr == "5" || cnp[0].chr == "6" then "20"
|
38
|
-
when
|
39
|
-
cnp[0].chr == "9" then "19" # oare se sare peste un an bisect intre 1800-2099 ?
|
40
|
-
else return false;
|
41
|
-
end
|
42
|
-
|
43
|
-
year = (year + cnp[1..2]).to_i
|
44
|
-
return false unless Date.valid_civil?(year,cnp[3..4].to_i,cnp[5..6].to_i)
|
45
|
-
rescue ArgumentError
|
46
|
-
return false
|
47
|
-
end
|
48
|
-
test_key = "279146358279"
|
49
|
-
(0..11).inject(0){|sum, n| sum += test_key[n].chr.to_i * cnp[n].chr.to_i} % 11 == cnp[12].chr.to_i
|
50
|
-
end
|
18
|
+
# Pas 2: Cele douasprezece produse obtinute se aduna si suma obtinuta se imparte la 11. Restul impartirii
|
19
|
+
# reprezinta cifra de control. Pentru un CNP valid acest rest va trebui sa coincida cu cifra de pe
|
20
|
+
# pozitia treisprezece din CNP-ul initial.
|
21
|
+
def valid?(cnp)
|
22
|
+
return false unless well_formed?(cnp) && valid_birthdate?(cnp)
|
23
|
+
|
24
|
+
(0..11).inject(0){|sum, n| sum += TEST_KEY[n].chr.to_i * cnp[n].chr.to_i} % 11 == cnp[12].chr.to_i
|
51
25
|
end
|
52
|
-
end
|
53
26
|
|
27
|
+
private
|
28
|
+
|
29
|
+
def well_formed?(cnp)
|
30
|
+
(cnp=~(/[^0-9]/)).nil? && cnp.size == 13
|
31
|
+
end
|
32
|
+
|
33
|
+
def valid_birthdate?(cnp)
|
34
|
+
year_code = cnp[0].chr.to_i
|
35
|
+
year = case year_code
|
36
|
+
when 1..2 then "19"
|
37
|
+
when 3..4 then "18"
|
38
|
+
when 5..6 then "20"
|
39
|
+
when 9 then "19" # oare se sare peste un an bisect intre 1800-2099 ?
|
40
|
+
else return false
|
41
|
+
end
|
42
|
+
year = (year + cnp[1..2]).to_i
|
43
|
+
Date.valid_civil?(year, cnp[3..4].to_i, cnp[5..6].to_i) ? true : false
|
44
|
+
rescue ArgumentError
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
54
49
|
end
|
55
50
|
end
|
@@ -1,30 +1,31 @@
|
|
1
1
|
module ActiveModel
|
2
2
|
module Validations
|
3
|
-
|
4
3
|
class IbanValidator < EachValidator
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
record.errors.add_on_blank(attribute) if value.blank? && !allow_blank
|
11
|
-
record.errors.add(attribute, message) unless Iban.valid?(value)
|
12
|
-
end
|
4
|
+
|
5
|
+
# use ord for ruby >= 1.9
|
6
|
+
USE_ORD = "".respond_to?(:ord)
|
7
|
+
|
8
|
+
include ActiveModel::Validations::EmptyBlankEachValidator
|
13
9
|
|
14
10
|
# Descrierea algoritmului:
|
15
11
|
# http://www.bnr.ro/files/d/Legislatie/EN/Reg_IBAN.pdf
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
use_ord ? (s[0].ord - 55).to_s : (s[0].to_i - 55).to_s
|
22
|
-
end.to_i % 97 == 1
|
23
|
-
rescue
|
24
|
-
false
|
25
|
-
end
|
12
|
+
def valid?(iban)
|
13
|
+
return false if iban.size < 3
|
14
|
+
transpose((iban.slice(4, iban.size) + iban[0..3])).to_i % 97 == 1
|
15
|
+
rescue
|
16
|
+
false
|
26
17
|
end
|
27
|
-
end
|
28
18
|
|
19
|
+
private
|
20
|
+
|
21
|
+
# replace letters according to algorithm
|
22
|
+
# algorithm conversion maps chars to ASCII value - 55
|
23
|
+
def transpose(iban)
|
24
|
+
iban.upcase.gsub(/[A-Z]/) do |s|
|
25
|
+
USE_ORD ? (s[0].ord - 55).to_s : (s[0].to_i - 55).to_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
29
30
|
end
|
30
31
|
end
|
data/lib/romanianvalidators.rb
CHANGED
@@ -6,6 +6,17 @@ module ActiveModel
|
|
6
6
|
%w(cif cnp iban bic)
|
7
7
|
end
|
8
8
|
|
9
|
+
module EmptyBlankEachValidator
|
10
|
+
def validate_each(record, attribute, value)
|
11
|
+
allow_blank = options.fetch(:allow_blank, false)
|
12
|
+
allow_nil = options.fetch(:allow_nil, false)
|
13
|
+
message = options.fetch(:message, nil)
|
14
|
+
record.errors.add_on_empty(attribute) if value.nil? && !allow_nil
|
15
|
+
record.errors.add_on_blank(attribute) if value.blank? && !allow_blank
|
16
|
+
record.errors.add(attribute, message) unless valid?(value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
romanianvalidators.each do |validator_name|
|
10
21
|
require "active_model/validations/#{validator_name}_validator"
|
11
22
|
end
|
data/romanianvalidators.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'romanianvalidators'
|
4
|
-
s.version = '0.1.
|
4
|
+
s.version = '0.1.4'
|
5
5
|
s.authors = ['Mihai Târnovan']
|
6
6
|
s.email = ['mihai.tarnovan@cubus.ro']
|
7
7
|
s.homepage = 'http://github.com/mtarnovan/romanianvalidators'
|
@@ -1,9 +1,9 @@
|
|
1
1
|
RO56TREZ0462107020101XXX
|
2
2
|
RO75TREZ0462116020201XXX
|
3
|
-
|
3
|
+
ro42TREZ04621030209XXXXX
|
4
4
|
RO57TREZ04621080206XXXXX
|
5
5
|
RO03TREZ0462107020201XXX
|
6
|
-
|
6
|
+
RO98trez04621030230XXXXX
|
7
7
|
RO24TREZ04621080230XXXXX
|
8
8
|
RO46TREZ04621170230XXXXX
|
9
9
|
RO43TREZ04621160250XXXXX
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: romanianvalidators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mihai Târnovan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|