* Add enclair_db option to UserDB.pm. Allows logging of enclair password
[interchange.git] / code / OrderCheck / isbn.oc
1 # Copyright 2008,2009 Interchange Development Group
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.  See the LICENSE file for details.
7
8 CodeDef isbn OrderCheck 1
9 CodeDef isbn Description ISBN-10/ISBN-13 check digit verification
10 CodeDef isbn Routine <<EOR
11 sub {
12         my($ref, $var, $val, $msg) = @_;
13         my($len);
14
15         if ($msg =~ s/^\s*(10|13)\s*//) {
16                 $len = $1;
17         }
18
19         $val =~ s/[^\dXx]//g;   # weed out non-digits
20         if ($val) {
21                 my @digits = split("", $val);
22                 my $sum = 0;
23                 my $check_digit = 0;
24                 my $modulo;
25
26                 if (@digits == 10 ) {
27                         # ISBN-10 number
28                         if ($len == 13) {
29                                 return (0, $var, errmsg("'%s' not a valid isbn-13 number", $val));
30                         }
31                         for(my $i=10; $i > 0; $i--) {
32                                 my $d = $digits[10 - $i];
33                                 if ($d =~ /[Xx]/) {
34                                         if ($i == 1) {
35                                                 $d = 10;
36                                         }
37                                         else {
38                                                 return (undef, $var, errmsg("'%s' not a valid isbn number", $val));
39                                         }
40                                 }
41                                 $sum += $d * $i;
42                         }
43                         return ( $sum%11 ? 0 : 1, $var, '' );
44                 } elsif (@digits == 13) {
45                         # ISBN-13/EAN number
46                         if ($len == 10) {
47                                 return (0, $var, errmsg("'%s' not a valid isbn-10 number", $val));
48                         }
49                         for (my $i = 0; $i < 12; $i++) {
50                                 if ($i % 2) {
51                                         $sum += 3 * $digits[$i];
52                                 } 
53                                 else {
54                                         $sum += $digits[$i];
55                                 }
56                         }
57                         
58                         if ($modulo = $sum % 10) {
59                                 $check_digit = 10 - $modulo;
60                         }
61
62                         if (pop(@digits) == $check_digit) {
63                                 # verification successful
64                                 return (1, $var, '');
65                         }
66                 }
67         }
68
69         return (undef, $var, errmsg("'%s' not a valid isbn number", $val));
70 }
71 EOR