From a6e1d7ba1ebb6b8d73eec602c2702cb6500f2150 Mon Sep 17 00:00:00 2001 From: Francesco Zanoni Date: Mon, 13 Aug 2018 20:21:13 +0200 Subject: [PATCH 1/3] add San Marino BBAN checksum management --- README.md | 2 -- php-iban.php | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 14f3913..1f9ade3 100644 --- a/README.md +++ b/README.md @@ -319,10 +319,8 @@ Your Help Wanted * If you know the URL of __national IBAN, BBAN or national checksum documentation__ from official sources, please let us know at [issue #39](https://github.com/globalcitizen/php-iban/issues/39) and [issue #41](https://github.com/globalcitizen/php-iban/issues/41). * __Faroe Islands__ (FO) banks do not respond, neither does the Danish National Bank who referred me to them. - * __Italy__ (IT) has a custom checksum system we need some help deciphering. Note that it is not the [Italian fiscal code](https://en.wikipedia.org/wiki/Italian_fiscal_code_card). * __Luxembourg__ (LU) does not seem to conform to any single checksum system. While some IBAN do validate with reasonably common systems, others don't or use others. The suggestion that Luxembourg has a national checksum system may in fact be incorrect. We need some clarification here, hopefully someone can dig up an official statement. * __Mauritania__ (MR) has a dual character checksum system but our example IBAN does not match MOD97-10 which would be the expected system. Previously the IBAN here was always fixed to '13' checksum digits, however as of registry v66 it is now dynamic, which suggests a changed or at least now nationally relaxed checksum system. - * __San Marino__ (SM) has an alphabetic checksum with an unknown algorithm. * If you are willing to spend some time searching, we could do with some more test IBANs for most countries, especially smaller ones... diff --git a/php-iban.php b/php-iban.php index 9903708..1caf3c4 100644 --- a/php-iban.php +++ b/php-iban.php @@ -1227,6 +1227,25 @@ function _iban_nationalchecksum_implementation_it($iban,$mode) { } } +# Implement the national checksum for a San Marino (SM) IBAN +function _iban_nationalchecksum_implementation_sm($iban,$mode) { + if($mode != 'set' && $mode != 'find' && $mode != 'verify') { return ''; } # blank value on return to distinguish from correct execution + $nationalchecksum = iban_get_nationalchecksum_part($iban); + $bban = iban_get_bban_part($iban); + $bban_less_checksum = substr($bban,1); + // San Marino adheres to Italian rules. + $expected_nationalchecksum = _italian($bban_less_checksum); + if($mode=='find') { + return $expected_nationalchecksum; + } + elseif($mode=='set') { + return _iban_nationalchecksum_set($iban,$expected_nationalchecksum); + } + elseif($mode=='verify') { + return (iban_get_nationalchecksum_part($iban) == $expected_nationalchecksum); + } +} + # Italian checksum # (Credit: Translated by Francesco Zanoni from http://community.visual-basic.it/lucianob/archive/2004/12/26/2464.aspx) function _italian($input) From 2e82821af609861d00dc7b98e69b9474fd08b84d Mon Sep 17 00:00:00 2001 From: Francesco Zanoni Date: Mon, 13 Aug 2018 21:30:11 +0200 Subject: [PATCH 2/3] Italy/San Marino BBAN checksum: added official source, minor improvements --- php-iban.php | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/php-iban.php b/php-iban.php index 1caf3c4..ae3a5fd 100644 --- a/php-iban.php +++ b/php-iban.php @@ -1229,30 +1229,17 @@ function _iban_nationalchecksum_implementation_it($iban,$mode) { # Implement the national checksum for a San Marino (SM) IBAN function _iban_nationalchecksum_implementation_sm($iban,$mode) { - if($mode != 'set' && $mode != 'find' && $mode != 'verify') { return ''; } # blank value on return to distinguish from correct execution - $nationalchecksum = iban_get_nationalchecksum_part($iban); - $bban = iban_get_bban_part($iban); - $bban_less_checksum = substr($bban,1); // San Marino adheres to Italian rules. - $expected_nationalchecksum = _italian($bban_less_checksum); - if($mode=='find') { - return $expected_nationalchecksum; - } - elseif($mode=='set') { - return _iban_nationalchecksum_set($iban,$expected_nationalchecksum); - } - elseif($mode=='verify') { - return (iban_get_nationalchecksum_part($iban) == $expected_nationalchecksum); - } + return _iban_nationalchecksum_implementation_it($iban,$mode); } -# Italian checksum +# Italian (and San Marino's) checksum # (Credit: Translated by Francesco Zanoni from http://community.visual-basic.it/lucianob/archive/2004/12/26/2464.aspx) +# (Source: European Commettee of Banking Standards' Register of European Account Numbers (TR201 V3.23 — FEBRUARY 2007), available at URL http://www.cnb.cz/cs/platebni_styk/iban/download/TR201.pdf) function _italian($input) { $digits = str_split('0123456789'); $letters = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ-. '); - $bbanWithoutChecksumLength = 22; $divisor = 26; $evenList = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); $oddList = array(1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23, 27, 28, 26); @@ -1260,7 +1247,7 @@ function _italian($input) // Character value computation $sum = 0; - for ($k = 0; $k < $bbanWithoutChecksumLength; $k++) { + for ($k = 0; $k < count($input); $k++) { $i = array_search($input[$k], $digits); if ($i === false) { From 757829ca299a4c1bb1a22ea2191d20cce3a1d2bc Mon Sep 17 00:00:00 2001 From: Francesco Zanoni Date: Mon, 13 Aug 2018 21:45:24 +0200 Subject: [PATCH 3/3] Italy/San Marino BBAN checksum: fixed length of BBAN without checksum --- php-iban.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php-iban.php b/php-iban.php index ae3a5fd..e9d8959 100644 --- a/php-iban.php +++ b/php-iban.php @@ -1235,11 +1235,13 @@ function _iban_nationalchecksum_implementation_sm($iban,$mode) { # Italian (and San Marino's) checksum # (Credit: Translated by Francesco Zanoni from http://community.visual-basic.it/lucianob/archive/2004/12/26/2464.aspx) -# (Source: European Commettee of Banking Standards' Register of European Account Numbers (TR201 V3.23 — FEBRUARY 2007), available at URL http://www.cnb.cz/cs/platebni_styk/iban/download/TR201.pdf) +# (Source: European Commettee of Banking Standards' Register of European Account Numbers (TR201 V3.23 — FEBRUARY 2007), +# available at URL http://www.cnb.cz/cs/platebni_styk/iban/download/TR201.pdf) function _italian($input) { $digits = str_split('0123456789'); $letters = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ-. '); + $lengthOfBbanWithoutChecksum = 22; $divisor = 26; $evenList = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); $oddList = array(1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23, 27, 28, 26); @@ -1247,7 +1249,7 @@ function _italian($input) // Character value computation $sum = 0; - for ($k = 0; $k < count($input); $k++) { + for ($k = 0; $k < $lengthOfBbanWithoutChecksum; $k++) { $i = array_search($input[$k], $digits); if ($i === false) {