File Coverage

blib/lib/Business/IBAN/Util.pm
Criterion Covered Total %
statement 20 20 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod 2 2 100.0
total 27 27 100.0


line stmt bran cond sub pod time code
1             package Business::IBAN::Util;
2 4     4   77045 use warnings;
  4         11  
  4         130  
3 4     4   23 use strict;
  4         12  
  4         84  
4              
5 4     4   20 use Exporter 'import';
  4         8  
  4         1229  
6             our @EXPORT_OK = qw( numify_iban mod97 );
7              
8             my %lettermap = do {
9             my $i = 10;
10             map +($_ => $i++), 'A'..'Z';
11             };
12              
13             sub numify_iban {
14 173     173 1 1655 my ($iban) = @_;
15              
16 173         504 my $to_check = substr($iban, 4) . substr($iban, 0, 4);
17 173         1524 $to_check =~ s/([A-Za-z])/$lettermap{uc($1)}/g;
18              
19 173         578 return $to_check;
20             }
21              
22             sub mod97 {
23 175     175 1 3056 my ($number) = @_;
24              
25             # Max 9 digits, safe for 32bit INT
26 175         306 my ($r, $l) = (0, 9);
27 175         3018 while ($number =~ s/^([0-9]{1,$l})//) {
28 701         1692 $r = $r . $1;
29 701         1237 $r %= 97;
30 701         5331 $l = 9 - length($r);
31             }
32 175         699 return $r;
33             }
34              
35             1;
36              
37             =head1 NAME
38              
39             Business::IBAN::Util - Helpers for the IBAN 97-test.
40              
41             =head1 SYNOPSIS
42              
43             #! /usr/bin/perl -w
44             use v5.14.0; # strict + feature
45              
46             use Business::IBAN::Util qw( numify_iban mod97 );
47              
48             print "IBAN: "; chomp(my $iban = <>);
49             my $as_num = numify_iban($iban);
50             my ($old_check) = $as_num =~ s{ (..) $}{00}x;
51             my $rest = mod97($as_num);
52             my $new_check = 98 - $rest;
53             if ($old_check != $new_check) {
54             my $new_iban = $iban; substr($new_iban, 2, 2, sprintf("%02u", $new_check));
55             say "Checksum not ok, should be $new_check: $new_iban"
56             }
57             else {
58             say "Checksum ok: $iban";
59             }
60              
61             =head1 DESCRIPTION
62              
63             These are helper functions to execute the 97-check on IBANs.
64              
65             =head2 numify_iban($iban)
66              
67             Put the first four characters at the end of the string. Transform all letters
68             into numbers ([Aa] => 10 .. [Zz] => 35). This results in a string of digits
69             [0-9] that will be used as a number for the 97-check.
70              
71             =head2 mod97($number)
72              
73             Returns the remainder of division by 97 (for a valid IBAN that should be 1).
74              
75             =head1 COPYRIGHT
76              
77             E MMXIII - Abe Timmerman
78              
79             =head1 LICENSE
80              
81             This library is free software; you can redistribute it and/or modify
82             it under the same terms as Perl itself.
83              
84             This program is distributed in the hope that it will be useful,
85             but WITHOUT ANY WARRANTY; without even the implied warranty of
86             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
87              
88             =cut