From e71ae539f75b62e188e0de83c1738834cc3605bb Mon Sep 17 00:00:00 2001 From: Francesco Zanoni Date: Sat, 11 Aug 2018 16:33:35 +0200 Subject: [PATCH 1/2] add Italian national checksum management --- php-iban.php | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/php-iban.php b/php-iban.php index 32d3b22..ee15ab2 100644 --- a/php-iban.php +++ b/php-iban.php @@ -144,7 +144,7 @@ function iban_mod97_10_checksum($numeric_representation) { return $checksum; } -# Perform MOD97-10 checksum calculation ('Germanic-level effiency' version - thanks Chris!) +# Perform MOD97-10 checksum calculation ('Germanic-level efficiency' version - thanks Chris!) function iban_mod97_10($numeric_representation) { global $__disable_iiban_gmp_extension; # prefer php5 gmp extension if available @@ -1209,6 +1209,59 @@ function _damm($input) { return $checksum; } +# Implement the national checksum for an Italian (IT) IBAN +function _iban_nationalchecksum_implementation_it($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); + $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) +{ + $digits = str_split('0123456789'); + $letters = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ-. '); + $bbanWithoutChecksumLength = 22; + $divisor = 26; + $evenList = [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 = [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]; + + // Character value computation + $sum = 0; + + for ($k = 0; $k < $bbanWithoutChecksumLength; $k++) { + + $i = array_search($input[$k], $digits); + if ($i === false) { + $i = array_search($input[$k], $letters); + } + + // In case of wrong characters, + // an unallowed checksum value is returned. + if ($i === false) { + return ''; + } + + $sum += (($k % 2) == 0 ? $oddList[$i] : $evenList[$i]); + + } + + return $letters[$sum % $divisor]; +} + + # Internal proxy function to access national checksum implementations # $iban = IBAN to work with (length and country must be valid, IBAN checksum and national checksum may be incorrect) # $mode = 'find', 'set', or 'verify' From 3f299fecb20446df14695f12c4c7e4b6f2d9a4f3 Mon Sep 17 00:00:00 2001 From: Francesco Zanoni Date: Sat, 11 Aug 2018 16:49:50 +0200 Subject: [PATCH 2/2] Italian national checksum management: switch to old array notation, for backward compatibility --- php-iban.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php-iban.php b/php-iban.php index ee15ab2..9903708 100644 --- a/php-iban.php +++ b/php-iban.php @@ -1235,8 +1235,8 @@ function _italian($input) $letters = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ-. '); $bbanWithoutChecksumLength = 22; $divisor = 26; - $evenList = [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 = [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]; + $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); // Character value computation $sum = 0;