romanianvalidators 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/mtarnovan/romanianvalidators.png)](https://travis-ci.org/mtarnovan/romanianvalidators)
|
1
|
+
# Romanian Validators [![Build Status](https://travis-ci.org/mtarnovan/romanianvalidators.png)](https://travis-ci.org/mtarnovan/romanianvalidators) [![Gem Version](https://badge.fury.io/rb/romanianvalidators.png)](http://badge.fury.io/rb/romanianvalidators) [![Code Climate](https://codeclimate.com/github/mtarnovan/romanianvalidators.png)](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
|