Algorithm-CheckDigits-v1.3.6000755001750001750 014144705550 16260 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/.perltidyrc000444001750001750 27114144705550 20557 0ustar00mathiasmathias000000000000-ci=2 -i=4 -l=78 -cti=0 -pt=1 -bt=1 -sbt=1 -bbt=1 -nsfs -nolc -nolq -ple -sct -se -st -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" Algorithm-CheckDigits-v1.3.6/Build.PL000444001750001750 222514144705550 17712 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 et si: use 5.006; use strict; use warnings; use Module::Build; my $builder = Module::Build->new( add_to_cleanup => [ 'Algorithm-CheckDigits-*' ], build_requires => { 'Probe::Perl' => 0, 'Test::More' => 0, 'Pod::Usage' => 1.30, }, configure_requires => { 'Module::Build' => 0.38 }, create_makefile_pl => 'small', dist_author => 'Mathias Weidner ', dist_version_from => 'lib/Algorithm/CheckDigits.pm', license => 'perl', module_name => 'Algorithm::CheckDigits', requires => { # Perl 5.10.1 includes "configure_requires" support # (see: Module::Build::Compat) 'perl' => '5.10.1', 'version' => 0, }, meta_merge => { resources => { repository => 'https://github.com/matwei-perl/Algorithm-CheckDigits', bugtracker => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Algorithm-CheckDigits', } }, script_files => [ 'bin/checkdigits.pl', ], ); $builder->create_build_script(); Algorithm-CheckDigits-v1.3.6/Changes000444001750001750 2127114144705550 17733 0ustar00mathiasmathias000000000000Revision history for Perl extension CheckDigits. v1.3.6 Tue Nov 16 11:38:44 CET 2021 - adjust repository to reflect move on GitHub v1.3.5 Wed Nov 18 16:18:35 CET 2020 - added links to repository and bugtracker - added entry to changelog - fix Bug #133767 v1.3.4 Thu 17. Nov 15:13:54 CET 2020 - revise lib/Algorithm/CheckDigits/M23_002.pm (irish TIN) - fix Bug #133031 v1.3.3 Di 14. Jul 19:20:56 CEST 2020 - reworked lib/Algorithm/CheckDigits.pm, allow 10-digit numbers, allow prepending of 'BE' before the digits - fix Bug #132950 v1.3.2 Mo 16. Mai 15:02:03 CEST 2016 - fix version strings 1.3.1 Mo 16. Mai 03:19:57 CEST 2016 - fix Bug #114347 - fix version numbers - require Perl version in Build.PL 1.3.0 Sun May 12 10:28:21 CEST 2013 - Changed description of modules to more meaningful text (at least I hope so). - Added plugin interface with examples in t/PluginLib*.pm and t/plugin*.t. 1.2.1 Sun Mar 3 22:51:45 CET 2013 - changed list items in POD from 0, 1, ... to S<0>, S<1>, ... according to a thread on the perl5 porters list (www.nntp.perl.org/group/perl.perl5.porters/2013/02/msg199355.html) David Wheeler: "Lists must start with 1. When it saw the 0, it assumed it was a definition list, so the numbers after that don't look right." 1.2.0 Fr 8. Jun 11:19:25 CEST 2012 - reworked Algorithm::CheckDigits::MXX_001.pm, added ABA routing numbers 1.1.2 Fr 8. Jun 09:22:35 CEST 2012 - added '=encoding iso-8859-1' to M11_004.pm, M11_006.pm, MBase_002.pm, MXX_003.pm, MXX_006.pm. This should prevent failures in the processing of the POD that contain non-ASCII characters. - corrected search and replacement lists in M10_011.pm 1.1.1 Do 3. Mar 10:16:59 CET 2011 - Reworked Algorithm::CheckDigits::M10_008 (sedol) to cop with alphanumerical SEDOL codes that are in use since March 2004. - There was also a flaw in the computation of the checksum that provided 10 instead of 0. - This closes bug number #66340 on CPAN. 1.1.0 Fr 12. Nov 19:10:39 CET 2010 - reworked Algorithm::CheckDigits::M10_001, added CUSIP - moved scripts/checkdigits.pl to bin/checkdigits.pl - added cgi-bin/checkdigits.cgi 1.0.0 Mo 13. Sep 21:27:23 CEST 2010 - reworked Algorithm::CheckDigits::MXX_001 0.90.0 Fr 10. Sep 15:52:51 CEST 2010 - added scripts/checkdigits.pl as sample script 0.53 Fr 20. Nov 11:46:08 CET 2009 - cleaned up documentation (thanks to Romuald Å»yłła for pointing me to more errors) - added $VERSION into all modules to close #36482 at rt.cpan.org 0.52 Mi 11. Nov 10:31:18 CET 2009 - added link to english description for ustid_pl 0.51 Mi 11. Nov 10:01:36 CET 2009 - corrected documentation for ustid_pl/vatnr_pl (thanks to Romuald Å»yłła for pointing me to the error) - reworked algorithm and documentation for esr5_ch according to http://www.sic.ch/de/dl_tkicch_dta.pdf (thanks to Romuald Å»yłła for pointing me to the error) 0.50 Fr 6. Jun 21:45:04 CEST 2008 - put $VERSION back into CheckDigits.pm 0.49 Fr 16. Mai 22:54:43 CEST 2008 - CheckDigits/MXX_002.pm computes checkdigits for CAS registration numbers with ten digits. 0.48 Di 9. Okt 01:07:02 CEST 2007 - keep VERSION in Makefile.PL 0.47 Di 9. Okt 00:45:07 CEST 2007 - provide Version in file VERSION - Makefile.PL: indicate minimum perl version (thanks to Slaven Rezic) 0.46 Mo 8. Okt 23:46:32 CEST 2007 - CheckDigits/M11_017.pm computes EC-No (EINECS, ELINCS) check digits. 0.45 So 7. Okt 12:00:25 CEST 2007 - CheckDigits.pm: CheckDigits() dies on unknown algorithm/method - CheckDigits.pm: IMEI and IMEISV are recognized (M10_001.pm) (Petri Oksanen made me aware that this wasn't so before) - CheckDigits/M10_001.pm recognizes that with IMEISV only the 14 most significant digits are taken for the computation of the checkdigit - reformatted CheckDigits.pm, CheckDigits/M10_001.pm 0.44 Mo Dez 11 00:46:30 CET 2006 - Method 97-002 (IBAN): allow min. 2, max. 30 digits/letters for BBAN 0.43 So Dez 10 23:35:31 CET 2006 - Method 97-002 (IBAN): allowed for more letters than just the country code and eliminated Math::BigInt (Thanks to Detlef Pilzecker). 0.42 Fr Dez 1 22:02:57 CET 2006 - Method 10-004: added code to handle ISBN-13 (mainly check whether first three digits are 978 or 979 and cope with hyphens) - CheckDigits.pm: Invocation as CheckDigits('isbn13') returns an Algorithm::CheckDigits::M10_004 object. - added tests for isbn13 0.41 Do Jun 29 00:34:04 CEST 2006 - added t/pod-coverage.t - added missing documentation 0.40 Mi Jun 28 23:31:00 CEST 2006 - fixed code examples in POD according to http://annocpan.org/~MAMAWE/Algorithm-CheckDigits-0.39/CheckDigits/MXX_002.pm - CheckDigits.pm: POD: corrected ABSTRACT - added t/pod.t to check for POD errors - fixed POD according to t/pod.t - Clarified POD for Algorithm/CheckDigits/MXX_006.pm 0.39 Sun, 12 Mar 2006 17:50:13 +0100 - Added Verhoeff scheme (Method XX-006) taking some code from Algorithm::Verhoeff. - Refined POD for CheckDigits.pm 0.38 Wed, 26 Jan 2005 22:48:10 +0100 - Refined Method M11-011 (now accepts full vatrn) - provided basic tests for above change 0.37 Wed, 14 Jul 2004 20:38:31 +0200 - Method 10-001: Added Support for ISIN - Method XX-004 (ustid_at) implemented - Method XX-005 (esr9_ch) implemented 0.36 Tue, 13 Jul 2004 23:45:02 +0200 - Method XX-003 (dem) implemented - Method XX-002 (cas) implemented 0.35 Sun, 11 Jul 2004 18:59:35 +0200 - Method XX-001 (pa_de) implemented 0.34a Fri, 09 Jul 2004 23:57:37 +0200 - Method 97-002 (iban) implemented 0.34 Wed, 14 Jun 2004 22:04:38 +0200 - Method 97-001 (ustid_be) implemented 0.33 Wed, 09 Jun 2004 22:04:38 +0200 - Method 23-002 (ustid_ie) implemented - Method 43-001 (code_39) implemented - Method 89-001 (ustid_lu) implemented 0.32 Fri, 14 May 2004 17:22:15 +0200 - Aaron W. West made me aware of a fault in MBase_001.pm (the code providing UPC check digits) and sent me a fix - added test routine for that failure 0.31 Tue, 11 May 2004 00:26:56 +0200 - Method 23-001 (dni_es) implemented - Renamed methods 001..010 0.30 Mon, 10 May 2004 01:00:14 +0200 - Method 16-001 (isan) implemented - Renamed methods 011, 012, 013, 014, 015 0.29 Wed, 05 May 2004 23:00:26 +0200 - Method 11-013 (vatrn_gr), 11-015 (esr5_ch) implemented - Renamed methods 016,017,018,019 - Changed man pages (synopsis) for some methods 0.27 Wed, 28 Apr 2004 23:22:41 +0200 - Method 11-012 implemented - Man page in CheckDigits.pm changed - Packages changed from CheckDigits... to Algorithm::CheckDigits... 0.26 Sun, 25 Apr 2004 22:43:39 +0200 - Method 11-011 implemented - Man page in CheckDigits.pm changed 0.25 Mon, 19 Apr 2004 22:54:56 +0200 - Method 11-016 implemented - Method 11-010 implemented 0.23 Sun, 18 Apr 2004 23:09:58 +0200 - Method 11-009 implemented 0.22 Sat, 17 Apr 2004 21:35:35 +0200 - Method 11-008 implemented 0.21 Thu, 15 Apr 2004 23:09:40 +0200 - Method 11-007 implemented - documented algorithm from Method M019 in the man page 0.20 Mon, 12 Apr 2004 23:28:05 +0200 - added tests with invalid data - Method Base-003 implemented 0.19 Thu, 26 Feb 2004 00:27:47 +0100 - took all test cases from www.pruefziffernberechnung.de into t/valid.data and inserted plan(... todo => ...) into t/valid.t - Method 019 implemented (algorithm not documented in man page!) 0.18 Thu, 25 Dec 2003 18:17:56 +0100 - Method 018 implemented 0.17 Fri, 28 Nov 2003 21:00:18 +0100 - Method 017 implemented - all tests for valid checkdigits into one testscript (valid.t) using one datafile (valid.data) 0.16 Die Nov 11 23:15:27 CET 2003 - Method 016 implemented - Typo in POD of M013.pm corrected 0.15 Mon Nov 10 23:23:10 CET 2003 - Method 015 implemented - Typo in POD of M014.pm corrected 0.14 Fre Okt 24 23:53:28 CEST 2003 - Method 014 implemented 0.13 Son Okt 19 23:25:09 CEST 2003 - Method 013 implemented 0.12 Die Okt 7 22:43:36 CEST 2003 - Method 012 implemented 0.11 Mon Okt 6 22:21:12 CEST 2003 - Method 011 implemented - Typo in POD of M010.pm corrected 0.10 Sam Sep 27 14:03:11 CEST 2003 - Method 010 implemented 0.09 Fre Sep 26 18:49:22 CEST 2003 - Method 009 implemented 0.08 Don Sep 25 21:41:26 CEST 2003 - Method 008 implemented 0.07 Mit Sep 24 22:06:44 CEST 2003 - Method 006, 007 implemented 0.05 Son Sep 21 15:17:46 CEST 2003 - Method 004, 005 implemented inclusive test routines and data - cleaned up code and doc for all methods so far 0.04 Sam Sep 20 23:54:09 CEST 2003 - Method 002, 003 implemented inclusive test routines and data 0.03 Fre Sep 19 23:15:04 CEST 2003 - Method 001 implemented inclusive test routines and data 0.01 Tue Sep 16 23:03:45 2003 - original version; created by h2xs 1.21 with options -A -X CheckDigits Algorithm-CheckDigits-v1.3.6/MANIFEST000444001750001750 374714144705550 17561 0ustar00mathiasmathias000000000000.perltidyrc bin/checkdigits.pl Build.PL cgi-bin/checkdigits.cgi Changes lib/Algorithm/CheckDigits.pm lib/Algorithm/CheckDigits/M07_001.pm lib/Algorithm/CheckDigits/M09_001.pm lib/Algorithm/CheckDigits/M10_001.pm lib/Algorithm/CheckDigits/M10_002.pm lib/Algorithm/CheckDigits/M10_003.pm lib/Algorithm/CheckDigits/M10_004.pm lib/Algorithm/CheckDigits/M10_005.pm lib/Algorithm/CheckDigits/M10_006.pm lib/Algorithm/CheckDigits/M10_008.pm lib/Algorithm/CheckDigits/M10_009.pm lib/Algorithm/CheckDigits/M10_010.pm lib/Algorithm/CheckDigits/M10_011.pm lib/Algorithm/CheckDigits/M11_001.pm lib/Algorithm/CheckDigits/M11_002.pm lib/Algorithm/CheckDigits/M11_003.pm lib/Algorithm/CheckDigits/M11_004.pm lib/Algorithm/CheckDigits/M11_006.pm lib/Algorithm/CheckDigits/M11_007.pm lib/Algorithm/CheckDigits/M11_008.pm lib/Algorithm/CheckDigits/M11_009.pm lib/Algorithm/CheckDigits/M11_010.pm lib/Algorithm/CheckDigits/M11_011.pm lib/Algorithm/CheckDigits/M11_012.pm lib/Algorithm/CheckDigits/M11_013.pm lib/Algorithm/CheckDigits/M11_015.pm lib/Algorithm/CheckDigits/M11_016.pm lib/Algorithm/CheckDigits/M11_017.pm lib/Algorithm/CheckDigits/M16_001.pm lib/Algorithm/CheckDigits/M23_001.pm lib/Algorithm/CheckDigits/M23_002.pm lib/Algorithm/CheckDigits/M43_001.pm lib/Algorithm/CheckDigits/M89_001.pm lib/Algorithm/CheckDigits/M97_001.pm lib/Algorithm/CheckDigits/M97_002.pm lib/Algorithm/CheckDigits/MBase_001.pm lib/Algorithm/CheckDigits/MBase_002.pm lib/Algorithm/CheckDigits/MBase_003.pm lib/Algorithm/CheckDigits/MXX_001.pm lib/Algorithm/CheckDigits/MXX_002.pm lib/Algorithm/CheckDigits/MXX_003.pm lib/Algorithm/CheckDigits/MXX_004.pm lib/Algorithm/CheckDigits/MXX_005.pm lib/Algorithm/CheckDigits/MXX_006.pm Makefile.PL MANIFEST META.json META.yml README t/94-version.t t/checkdigits.t t/ecno.t t/esr5_ch.t t/iban.t t/imei.t t/isbn13.t t/nip.t t/plugina.t t/pluginb-without.t t/pluginb.t t/PluginLibA.pm t/PluginLibB.pm t/pod-coverage.t t/pod.t t/script-checkdigits.t t/sedol.t t/tin_ie.t t/upc.t t/ustid_be.t t/valid.data t/valid.t Algorithm-CheckDigits-v1.3.6/META.json000444001750001750 1644614144705550 20071 0ustar00mathiasmathias000000000000{ "abstract" : "Perl extension to generate and test check digits", "author" : [ "Mathias Weidner " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4231", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Algorithm-CheckDigits", "prereqs" : { "build" : { "requires" : { "Pod::Usage" : "1.3", "Probe::Perl" : "0", "Test::More" : "0" } }, "configure" : { "requires" : { "Module::Build" : "0.38" } }, "runtime" : { "requires" : { "perl" : "v5.10.1", "version" : "0" } } }, "provides" : { "Algorithm::CheckDigits" : { "file" : "lib/Algorithm/CheckDigits.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M07_001" : { "file" : "lib/Algorithm/CheckDigits/M07_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M09_001" : { "file" : "lib/Algorithm/CheckDigits/M09_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_001" : { "file" : "lib/Algorithm/CheckDigits/M10_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_002" : { "file" : "lib/Algorithm/CheckDigits/M10_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_003" : { "file" : "lib/Algorithm/CheckDigits/M10_003.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_004" : { "file" : "lib/Algorithm/CheckDigits/M10_004.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_005" : { "file" : "lib/Algorithm/CheckDigits/M10_005.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_006" : { "file" : "lib/Algorithm/CheckDigits/M10_006.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_008" : { "file" : "lib/Algorithm/CheckDigits/M10_008.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_009" : { "file" : "lib/Algorithm/CheckDigits/M10_009.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_010" : { "file" : "lib/Algorithm/CheckDigits/M10_010.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M10_011" : { "file" : "lib/Algorithm/CheckDigits/M10_011.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_001" : { "file" : "lib/Algorithm/CheckDigits/M11_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_002" : { "file" : "lib/Algorithm/CheckDigits/M11_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_003" : { "file" : "lib/Algorithm/CheckDigits/M11_003.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_004" : { "file" : "lib/Algorithm/CheckDigits/M11_004.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_006" : { "file" : "lib/Algorithm/CheckDigits/M11_006.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_007" : { "file" : "lib/Algorithm/CheckDigits/M11_007.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_008" : { "file" : "lib/Algorithm/CheckDigits/M11_008.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_009" : { "file" : "lib/Algorithm/CheckDigits/M11_009.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_010" : { "file" : "lib/Algorithm/CheckDigits/M11_010.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_011" : { "file" : "lib/Algorithm/CheckDigits/M11_011.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_012" : { "file" : "lib/Algorithm/CheckDigits/M11_012.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_013" : { "file" : "lib/Algorithm/CheckDigits/M11_013.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_015" : { "file" : "lib/Algorithm/CheckDigits/M11_015.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_016" : { "file" : "lib/Algorithm/CheckDigits/M11_016.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M11_017" : { "file" : "lib/Algorithm/CheckDigits/M11_017.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M16_001" : { "file" : "lib/Algorithm/CheckDigits/M16_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M23_001" : { "file" : "lib/Algorithm/CheckDigits/M23_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M23_002" : { "file" : "lib/Algorithm/CheckDigits/M23_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M43_001" : { "file" : "lib/Algorithm/CheckDigits/M43_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M89_001" : { "file" : "lib/Algorithm/CheckDigits/M89_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M97_001" : { "file" : "lib/Algorithm/CheckDigits/M97_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::M97_002" : { "file" : "lib/Algorithm/CheckDigits/M97_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MBase_001" : { "file" : "lib/Algorithm/CheckDigits/MBase_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MBase_002" : { "file" : "lib/Algorithm/CheckDigits/MBase_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MBase_003" : { "file" : "lib/Algorithm/CheckDigits/MBase_003.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_001" : { "file" : "lib/Algorithm/CheckDigits/MXX_001.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_002" : { "file" : "lib/Algorithm/CheckDigits/MXX_002.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_003" : { "file" : "lib/Algorithm/CheckDigits/MXX_003.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_004" : { "file" : "lib/Algorithm/CheckDigits/MXX_004.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_005" : { "file" : "lib/Algorithm/CheckDigits/MXX_005.pm", "version" : "v1.3.6" }, "Algorithm::CheckDigits::MXX_006" : { "file" : "lib/Algorithm/CheckDigits/MXX_006.pm", "version" : "v1.3.6" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Algorithm-CheckDigits" }, "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "https://github.com/matwei-perl/Algorithm-CheckDigits" } }, "version" : "v1.3.6", "x_serialization_backend" : "JSON::PP version 4.02" } Algorithm-CheckDigits-v1.3.6/META.yml000444001750001750 1223714144705550 17713 0ustar00mathiasmathias000000000000--- abstract: 'Perl extension to generate and test check digits' author: - 'Mathias Weidner ' build_requires: Pod::Usage: '1.3' Probe::Perl: '0' Test::More: '0' configure_requires: Module::Build: '0.38' dynamic_config: 1 generated_by: 'Module::Build version 0.4231, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Algorithm-CheckDigits provides: Algorithm::CheckDigits: file: lib/Algorithm/CheckDigits.pm version: v1.3.6 Algorithm::CheckDigits::M07_001: file: lib/Algorithm/CheckDigits/M07_001.pm version: v1.3.6 Algorithm::CheckDigits::M09_001: file: lib/Algorithm/CheckDigits/M09_001.pm version: v1.3.6 Algorithm::CheckDigits::M10_001: file: lib/Algorithm/CheckDigits/M10_001.pm version: v1.3.6 Algorithm::CheckDigits::M10_002: file: lib/Algorithm/CheckDigits/M10_002.pm version: v1.3.6 Algorithm::CheckDigits::M10_003: file: lib/Algorithm/CheckDigits/M10_003.pm version: v1.3.6 Algorithm::CheckDigits::M10_004: file: lib/Algorithm/CheckDigits/M10_004.pm version: v1.3.6 Algorithm::CheckDigits::M10_005: file: lib/Algorithm/CheckDigits/M10_005.pm version: v1.3.6 Algorithm::CheckDigits::M10_006: file: lib/Algorithm/CheckDigits/M10_006.pm version: v1.3.6 Algorithm::CheckDigits::M10_008: file: lib/Algorithm/CheckDigits/M10_008.pm version: v1.3.6 Algorithm::CheckDigits::M10_009: file: lib/Algorithm/CheckDigits/M10_009.pm version: v1.3.6 Algorithm::CheckDigits::M10_010: file: lib/Algorithm/CheckDigits/M10_010.pm version: v1.3.6 Algorithm::CheckDigits::M10_011: file: lib/Algorithm/CheckDigits/M10_011.pm version: v1.3.6 Algorithm::CheckDigits::M11_001: file: lib/Algorithm/CheckDigits/M11_001.pm version: v1.3.6 Algorithm::CheckDigits::M11_002: file: lib/Algorithm/CheckDigits/M11_002.pm version: v1.3.6 Algorithm::CheckDigits::M11_003: file: lib/Algorithm/CheckDigits/M11_003.pm version: v1.3.6 Algorithm::CheckDigits::M11_004: file: lib/Algorithm/CheckDigits/M11_004.pm version: v1.3.6 Algorithm::CheckDigits::M11_006: file: lib/Algorithm/CheckDigits/M11_006.pm version: v1.3.6 Algorithm::CheckDigits::M11_007: file: lib/Algorithm/CheckDigits/M11_007.pm version: v1.3.6 Algorithm::CheckDigits::M11_008: file: lib/Algorithm/CheckDigits/M11_008.pm version: v1.3.6 Algorithm::CheckDigits::M11_009: file: lib/Algorithm/CheckDigits/M11_009.pm version: v1.3.6 Algorithm::CheckDigits::M11_010: file: lib/Algorithm/CheckDigits/M11_010.pm version: v1.3.6 Algorithm::CheckDigits::M11_011: file: lib/Algorithm/CheckDigits/M11_011.pm version: v1.3.6 Algorithm::CheckDigits::M11_012: file: lib/Algorithm/CheckDigits/M11_012.pm version: v1.3.6 Algorithm::CheckDigits::M11_013: file: lib/Algorithm/CheckDigits/M11_013.pm version: v1.3.6 Algorithm::CheckDigits::M11_015: file: lib/Algorithm/CheckDigits/M11_015.pm version: v1.3.6 Algorithm::CheckDigits::M11_016: file: lib/Algorithm/CheckDigits/M11_016.pm version: v1.3.6 Algorithm::CheckDigits::M11_017: file: lib/Algorithm/CheckDigits/M11_017.pm version: v1.3.6 Algorithm::CheckDigits::M16_001: file: lib/Algorithm/CheckDigits/M16_001.pm version: v1.3.6 Algorithm::CheckDigits::M23_001: file: lib/Algorithm/CheckDigits/M23_001.pm version: v1.3.6 Algorithm::CheckDigits::M23_002: file: lib/Algorithm/CheckDigits/M23_002.pm version: v1.3.6 Algorithm::CheckDigits::M43_001: file: lib/Algorithm/CheckDigits/M43_001.pm version: v1.3.6 Algorithm::CheckDigits::M89_001: file: lib/Algorithm/CheckDigits/M89_001.pm version: v1.3.6 Algorithm::CheckDigits::M97_001: file: lib/Algorithm/CheckDigits/M97_001.pm version: v1.3.6 Algorithm::CheckDigits::M97_002: file: lib/Algorithm/CheckDigits/M97_002.pm version: v1.3.6 Algorithm::CheckDigits::MBase_001: file: lib/Algorithm/CheckDigits/MBase_001.pm version: v1.3.6 Algorithm::CheckDigits::MBase_002: file: lib/Algorithm/CheckDigits/MBase_002.pm version: v1.3.6 Algorithm::CheckDigits::MBase_003: file: lib/Algorithm/CheckDigits/MBase_003.pm version: v1.3.6 Algorithm::CheckDigits::MXX_001: file: lib/Algorithm/CheckDigits/MXX_001.pm version: v1.3.6 Algorithm::CheckDigits::MXX_002: file: lib/Algorithm/CheckDigits/MXX_002.pm version: v1.3.6 Algorithm::CheckDigits::MXX_003: file: lib/Algorithm/CheckDigits/MXX_003.pm version: v1.3.6 Algorithm::CheckDigits::MXX_004: file: lib/Algorithm/CheckDigits/MXX_004.pm version: v1.3.6 Algorithm::CheckDigits::MXX_005: file: lib/Algorithm/CheckDigits/MXX_005.pm version: v1.3.6 Algorithm::CheckDigits::MXX_006: file: lib/Algorithm/CheckDigits/MXX_006.pm version: v1.3.6 requires: perl: v5.10.1 version: '0' resources: bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Algorithm-CheckDigits license: http://dev.perl.org/licenses/ repository: https://github.com/matwei-perl/Algorithm-CheckDigits version: v1.3.6 x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Algorithm-CheckDigits-v1.3.6/Makefile.PL000444001750001750 44714144705550 20354 0ustar00mathiasmathias000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.4231 require 5.010001; use Module::Build::Compat 0.02; Module::Build::Compat->run_build_pl(args => \@ARGV); require Module::Build; Module::Build::Compat->write_makefile(build_class => 'Module::Build'); Algorithm-CheckDigits-v1.3.6/README000444001750001750 122514144705550 17275 0ustar00mathiasmathias000000000000CheckDigits v1.3.6 ================== This library provides several modules to compute or validate check digits. There is a executable script that may be used at the command line to compute or validate check digits. Further there is a sample CGI script that may be used to setup a web service to validate check digits in your webbrowser. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires no other modules and libraries. COPYRIGHT AND LICENCE Copyright (C) 2003-2020 Mathias Weidner This module may be distributed under the same license as perl itself. Algorithm-CheckDigits-v1.3.6/bin000755001750001750 014144705550 17030 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/bin/checkdigits.pl000444001750001750 1247414144705550 22033 0ustar00mathiasmathias000000000000#!/usr/bin/perl -w # vim: set ts=4 sw=4 tw=78 et si: # use strict; use Algorithm::CheckDigits; use Getopt::Long; use Pod::Usage; use version; our $VERSION = qv('v1.3.6'); my %opt; GetOptions(\%opt, 'algorithm=s', 'help', 'man'); pod2usage(-exitstatus => 0, -input => \*DATA) if $opt{help}; pod2usage(-exitstatus => 0, -verbose => 2, -input => \*DATA) if $opt{man}; my $cmd = shift || 'check'; pod2usage(0) unless $cmd; if ($cmd =~ /^list(_alg(orithms)?)?$/i) { my %descr = Algorithm::CheckDigits::method_descriptions(); for my $method (Algorithm::CheckDigits->method_list()) { print $method, ': ', $descr{$method}, "\n"; } exit 0; } if ($cmd =~ /^descr(ibe)?$/i) { while (my $method = shift @ARGV) { print join(': ',Algorithm::CheckDigits->method_descriptions($method)) , "\n"; } exit 0; } my $algorithm = determine_algorithm(\%opt); my $cd = CheckDigits($algorithm); my $complete = sub { $cd->complete($_[0]); }; my $check = sub { $cd->is_valid($_[0]) ? "valid" : "not valid"; }; my $checkdigit = sub { $cd->checkdigit($_[0]); }; my %cmdtable = ( complete => $complete, check => $check, checkdigit => $checkdigit, ); if (my $action = $cmdtable{$cmd}) { if (0 < scalar @ARGV) { while (my $number = shift) { printf "%s\n", $action->($number); } } else { print STDERR "Reading numbers from STDIN\n"; while (my $number = <>) { $number =~ s/\s+$//; printf "%s\n", $action->($number); } } } else { pod2usage(1); } #----- only functions following ----- sub determine_algorithm { my $opt = shift; return $opt->{algorithm} if $opt->{algorithm}; if ($0 =~ /^checkdigit(?:s)?-?(.*)$/i) { return $1 ? $1 : undef; } return $0; } # determine algorithm() __END__ =head1 NAME checkdigits - check or generate check digits =head1 VERSION This document describes checkdigits v1.3.3 =head1 SYNOPSIS checkdigits [Options] command [[number] ...] options: -algorithm alg - use this algorithm commands: check - check validity of number containing checkdigit checkdigit - return checkdigit belonging to number complete - return number completed with checkdigit list_algorithms - list all known algorithms describe - describe the given algorithms =head1 DESCRIPTION This is a command line program that may be used to compute any checkdigit known by the perl module Algorithm::CheckDigits. =head1 OPTIONS AND COMMANDS =head2 Options =head3 -algorithm alg Compute checkdigits according to algorithm I. Instead of providing the algorithm with this option, you may choose to rename the program to the name of the algorithm or to C<< checkdigits- >> followed by the name of the algorithm. You must provide the algorithm with any of these means or the program will not compute any checkdigit. =head2 Commands =head3 check =head3 checkdigit =head3 complete When called with this command, the program will take the number compute the appropriate checkdigits and return the complete number with checkdigits. =head3 describe Called with this command, the program will list the algorithm handles given on the command line with a short description or the word "unknown" for any unknown algorithm. See command I for a list of known algorithms. =head3 list_algorithms Called with this command, the program will list all known algorithms together with a short description and then exit. =head1 DIAGNOSTICS =head1 CONFIGURATION AND ENVIRONMENT At the moment the program doesn't recognise any environment variables. The algorithm to use may be predefined by renaming the program to the name of the algorithm or to C followed by the name of the algorithm. =head1 AUTHOR Mathias Weidner C<< mamawe@cpan.org >> =head1 LICENCE AND COPYRIGHT Copyright (c) 2010-2020, Mathias Weidner C<< mamawe@cpan.org >>. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =head1 DISCLAIMER OF WARRANTY BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Algorithm-CheckDigits-v1.3.6/cgi-bin000755001750001750 014144705550 17570 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/cgi-bin/checkdigits.cgi000555001750001750 204514144705550 22676 0ustar00mathiasmathias000000000000#!/usr/bin/perl -w # vim: ts=4 sw=4 tw=78 et si: # use strict; use Algorithm::CheckDigits; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); my $algorithm = param('algorithm'); my $number = param('number'); my $ok = ''; my @all_algorithms; my %all_labels; if ($ENV{ALL_ALGORITHMS}) { @all_algorithms = split /,/, $ENV{ALL_ALGORITHMS}; } else { @all_algorithms = Algorithm::CheckDigits::method_list(); } %all_labels = Algorithm::CheckDigits::method_descriptions(@all_algorithms); if ($number and $algorithm) { my $cd = CheckDigits($algorithm); if ($cd->is_valid($number)) { $ok = "$number is a valid $algorithm number"; param('number',''); } else { $ok = "$number is not valid with algorithm $algorithm"; } } print header(), start_html(), start_form(), textfield('number'), popup_menu(-name => 'algorithm', -values => \@all_algorithms, -labels => \%all_labels), submit('check'), end_form(), $ok, end_html(), "\n"; exit 0; Algorithm-CheckDigits-v1.3.6/lib000755001750001750 014144705550 17026 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/lib/Algorithm000755001750001750 014144705550 20754 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits.pm000444001750001750 5737314144705550 23667 0ustar00mathiasmathias000000000000# vim: ts=4 sw=4 tw=78 et si: package Algorithm::CheckDigits; use 5.006; use strict; use warnings; use Carp; use vars qw($AUTOLOAD); require Exporter; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use CheckDigits ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( CheckDigits method_descriptions method_list print_methods ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( CheckDigits ); use version; our $VERSION = qv('v1.3.6'); my %methods = ( 'upc' => [ 'Algorithm::CheckDigits::MBase_001', 'Universal Product Code, UPC (US, CA)' ], 'blutbeutel' => [ 'Algorithm::CheckDigits::MBase_002', 'Eurocode, blood bags' ], 'bzue_de' => [ 'Algorithm::CheckDigits::MBase_002', 'Beleglose Zahlscheinüberweisung, BZÜ (DE)' ], 'ustid_de' => [ 'Algorithm::CheckDigits::MBase_002', 'Umsatzsteuer-Identifikationsnummer (DE)' ], 'sici' => [ 'Algorithm::CheckDigits::MBase_003', 'Value Added Tax number, VAT (DE)' ], 'euronote' => [ 'Algorithm::CheckDigits::M09_001', 'Euro bank notes, EUR' ], 'amex' => [ 'Algorithm::CheckDigits::M10_001', 'American Express credit cards' ], 'bahncard' => [ 'Algorithm::CheckDigits::M10_001', 'DB Bahncard (DE)' ], 'cusip' => [ 'Algorithm::CheckDigits::M10_001', 'Committee on Uniform Security Identification Procedures, CUSIP (US)' ], 'diners' => [ 'Algorithm::CheckDigits::M10_001', q(Diner's club credit cards) ], 'discover' => [ 'Algorithm::CheckDigits::M10_001', 'Discover credit cards' ], 'enroute' => [ 'Algorithm::CheckDigits::M10_001', 'EnRoute credit cards' ], 'eurocard' => [ 'Algorithm::CheckDigits::M10_001', 'Eurocard credit cards' ], 'happydigits' => [ 'Algorithm::CheckDigits::M10_001', 'Happy Digits (DE)' ], 'jcb' => [ 'Algorithm::CheckDigits::M10_001', 'JCB credit cards' ], 'klubkarstadt' => [ 'Algorithm::CheckDigits::M10_001', 'Klub Karstadt (DE)' ], 'mastercard' => [ 'Algorithm::CheckDigits::M10_001', 'Mastercard credit cards' ], 'miles&more' => [ 'Algorithm::CheckDigits::M10_001', 'Miles & More, Lufthansa (DE)' ], 'visa' => [ 'Algorithm::CheckDigits::M10_001', 'VISA credit cards' ], 'isin' => [ 'Algorithm::CheckDigits::M10_001', 'International Securities Identifikation Number, ISIN' ], 'imei' => [ 'Algorithm::CheckDigits::M10_001', 'International Mobile Station Equipment Identity, IMEI' ], 'imeisv' => [ 'Algorithm::CheckDigits::M10_001', 'International Mobile Station Equipment Identity and Software Version Number' ], 'siren' => [ 'Algorithm::CheckDigits::M10_002', 'SIREN (FR)' ], 'siret' => [ 'Algorithm::CheckDigits::M10_002', 'SIRET (FR)' ], 'ismn' => [ 'Algorithm::CheckDigits::M10_003', 'International Standard Music Number, ISMN' ], 'ean' => [ 'Algorithm::CheckDigits::M10_004', 'European Article Number, EAN' ], 'iln' => [ 'Algorithm::CheckDigits::M10_004', 'Global Location Number, GLN' ], 'nve' => [ 'Algorithm::CheckDigits::M10_004', 'Nummer der Versandeinheit, NVE, SSCC' ], '2aus5' => [ 'Algorithm::CheckDigits::M10_004', '2 aus 5, 2 of 5, 2/5' ], 'isbn13' => [ 'Algorithm::CheckDigits::M10_004', 'International Standard Book Number, ISBN13' ], 'identcode_dp' => [ 'Algorithm::CheckDigits::M10_005', 'Identcode Deutsche Post AG (DE)' ], 'leitcode_dp' => [ 'Algorithm::CheckDigits::M10_005', 'Leitcode Deutsche Post AG (DE)' ], 'rentenversicherung' => [ 'Algorithm::CheckDigits::M10_006', 'Rentenversicherungsnummer, VSNR (DE)' ], 'sedol' => [ 'Algorithm::CheckDigits::M10_008', 'Stock Exchange Daily Official List, SEDOL (GB)' ], 'betriebsnummer' => [ 'Algorithm::CheckDigits::M10_009', 'Betriebsnummer (DE)' ], 'postcheckkonti' => [ 'Algorithm::CheckDigits::M10_010', 'Postscheckkonti (CH)' ], 'ups' => [ 'Algorithm::CheckDigits::M10_011', 'United Parcel Service, UPS' ], 'isbn' => [ 'Algorithm::CheckDigits::M11_001', 'International Standard Book Number, ISBN10' ], 'issn' => [ 'Algorithm::CheckDigits::M11_001', 'International Standard Serial Number, ISSN' ], 'ustid_pt' => [ 'Algorithm::CheckDigits::M11_001', 'Umsatzsteuer-Identifikationsnummer (PT)' ], 'vatrn_pt' => [ 'Algorithm::CheckDigits::M11_001', 'Value Added Tax number, VAT (PT)' ], 'hkid' => [ 'Algorithm::CheckDigits::M11_001', 'Hong Kong Identity Card, HKID (HK)' ], 'wagonnr_br' => [ 'Algorithm::CheckDigits::M11_001', 'Codificação dos vagões (BR)' ], 'nhs_gb' => [ 'Algorithm::CheckDigits::M11_001', 'National Health Service, NHS (GB)' ], 'vat_sl' => [ 'Algorithm::CheckDigits::M11_001', 'Value Added Tax number, VAT (SL)' ], 'pzn' => [ 'Algorithm::CheckDigits::M11_002', 'Pharmazentralnummer (DE)' ], 'pkz' => [ 'Algorithm::CheckDigits::M11_003', 'Personenkennzahl der DDR' ], 'cpf' => [ 'Algorithm::CheckDigits::M11_004', 'Cadastro de Pessoas Físicas, CPF (BR)' ], 'titulo_eleitor' => [ 'Algorithm::CheckDigits::M11_004', 'Título Eleitoral (BR)' ], 'ccc_es' => [ 'Algorithm::CheckDigits::M11_006', 'Código de Cuenta Corriente, CCC (ES)' ], 'ustid_fi' => [ 'Algorithm::CheckDigits::M11_007', 'Umsatzsteuer-Identifikationsnummer (FI)' ], 'vatrn_fi' => [ 'Algorithm::CheckDigits::M11_007', 'Value Added Tax number, VAT (FI)' ], 'ustid_dk' => [ 'Algorithm::CheckDigits::M11_008', 'Umsatzsteuer-Identifikationsnummer (DK)' ], 'vatrn_dk' => [ 'Algorithm::CheckDigits::M11_008', 'Value Added Tax number, VAT (DK)' ], 'nric_sg' => [ 'Algorithm::CheckDigits::M11_009', 'National Registration Identity Card, NRIC (SG)' ], 'ahv_ch' => [ 'Algorithm::CheckDigits::M11_010', 'Alters- und Hinterlassenenversicherungsnummer, AHV (CH)' ], 'ustid_nl' => [ 'Algorithm::CheckDigits::M11_011', 'Umsatzsteuer-Identifikationsnummer (NL)' ], 'vatrn_nl' => [ 'Algorithm::CheckDigits::M11_011', 'Value Added Tax number, VAT (NL)' ], 'bwpk_de' => [ 'Algorithm::CheckDigits::M11_012', 'Personenkennummer der Bundeswehr (DE)' ], 'ustid_gr' => [ 'Algorithm::CheckDigits::M11_013', 'Umsatzsteuer-Identifikationsnummer (GR)' ], 'vatrn_gr' => [ 'Algorithm::CheckDigits::M11_013', 'Value Added Tax number, VAT (GR)' ], 'esr5_ch' => [ 'Algorithm::CheckDigits::M11_015', 'Einzahlungsschein mit Referenz, ESR5 (CH)' ], 'ustid_pl' => [ 'Algorithm::CheckDigits::M11_016', 'Umsatzsteuer-Identifikationsnummer (PL)' ], 'vatrn_pl' => [ 'Algorithm::CheckDigits::M11_016', 'Value Added Tax number, VAT (PL)' ], 'nip' => [ 'Algorithm::CheckDigits::M11_016', 'numer identyfikacji podatkowej, NIP' ], 'ecno' => [ 'Algorithm::CheckDigits::M11_017', 'European Commission number, EC-No (for chemicals)' ], 'einecs' => [ 'Algorithm::CheckDigits::M11_017', 'European Inventory of Existing Commercial Chemical Substances, EINECS' ], 'elincs' => [ 'Algorithm::CheckDigits::M11_017', 'European List of Notified Chemical Substances, ELINCS' ], 'isan' => [ 'Algorithm::CheckDigits::M16_001', 'International Standard Audiovisual Number, ISAN' ], 'dni_es' => [ 'Algorithm::CheckDigits::M23_001', 'Documento nacional de identidad (ES)' ], 'ustid_ie' => [ 'Algorithm::CheckDigits::M23_002', 'Umsatzsteuer-Identifikationsnummer (IE)' ], 'vatrn_ie' => [ 'Algorithm::CheckDigits::M23_002', 'Value Added Tax number, VAT (IE)' ], 'tin_ie' => [ 'Algorithm::CheckDigits::M23_002', 'Tax Identification Number (IE)' ], 'code_39' => [ 'Algorithm::CheckDigits::M43_001', 'Code39, 3 of 9' ], 'ustid_lu' => [ 'Algorithm::CheckDigits::M89_001', 'Umsatzsteuer-Identifikationsnummer (LU)' ], 'vatrn_lu' => [ 'Algorithm::CheckDigits::M89_001', 'Value Added Tax number, VAT (LU)' ], 'ustid_be' => [ 'Algorithm::CheckDigits::M97_001', 'Umsatzsteuer-Identifikationsnummer (BE)' ], 'vatrn_be' => [ 'Algorithm::CheckDigits::M97_001', 'Value Added Tax number, VAT (BE)' ], 'iban' => [ 'Algorithm::CheckDigits::M97_002', 'International Bank Account Number (IBAN)' ], 'pa_de' => [ 'Algorithm::CheckDigits::MXX_001', 'Personalausweis (DE)' ], 'aba_rn' => [ 'Algorithm::CheckDigits::MXX_001', 'American Bankers Association routing number (ABA RN)' ], 'cas' => [ 'Algorithm::CheckDigits::MXX_002', 'Chemical abstract service, CAS' ], 'dem' => [ 'Algorithm::CheckDigits::MXX_003', 'Deutsche Mark Banknoten, DEM' ], 'ustid_at' => [ 'Algorithm::CheckDigits::MXX_004', 'Umsatzsteuer-Identifikationsnummer (AT)' ], 'vatrn_at' => [ 'Algorithm::CheckDigits::MXX_004', 'Value Added Tax number, VAT (AT)' ], 'esr9_ch' => [ 'Algorithm::CheckDigits::MXX_005', 'Einzahlungsschein mit Referenz, ESR9 (CH)' ], 'verhoeff' => [ 'Algorithm::CheckDigits::MXX_006', 'Verhoeff scheme' ], ); sub CheckDigits { my $method = shift || ''; if ( my $pkg = $methods{ lc($method) } ) { my $module = $pkg->[0]; my $file = $pkg->[0]; $file =~ s{::}{/}g; require "$file.pm"; return new $module($method); } else { die "Don't know checkdigit algorithm for '$method'!"; } } # CheckDigits() sub method_list { my @methods = (); foreach my $method ( sort keys %methods ) { push @methods, $method; } return wantarray ? @methods : \@methods; } # method_list() sub method_descriptions { my @meths = @_; if ($meths[0] eq 'Algorithm::CheckDigits') { # it was called Algorithm::CheckDigits->method_descriptions shift @meths; } if (0 == scalar @meths) { @meths = keys %methods; } my %descr = map { $_ => ($methods{$_}) ? $methods{$_}->[1] : 'unknown' } @meths; return wantarray ? %descr : \%descr; } # method_descriptions() sub plug_in { if ('Algorithm::CheckDigits' eq $_[0]) { shift; } my $module = shift || die "you need to specify a module except 'Algorithm::CheckDigits'"; my $descr = shift || "algorithm of module $module"; my $key = lc shift || 'plalg'; if (exists $methods{$key}) { $key .= ',1'; } while (exists $methods{$key}) { $key =~ s/(\d+)$/my $y = $1; ++$y/e; } $methods{$key} = [ $module, $descr ]; return $key; } # plug_in() sub print_methods { foreach my $method ( sort keys %methods ) { print "$method => $methods{$method}\n"; } } # print_methods() sub AUTOLOAD { my $self = shift; my $attr = $AUTOLOAD; unless ( $attr =~ /^Algorithm::CheckDigits::[A-Za-z_0-9]*$/ ) { croak "$attr is not defined"; } return ''; } # AUTOLOAD() sub DESTROY { } # Preloaded methods go here. 1; __END__ =head1 NAME Algorithm::CheckDigits - Perl extension to generate and test check digits =head1 SYNOPSIS perl -MAlgorithm::CheckDigits -e Algorithm::CheckDigits::print_methods or use Algorithm::CheckDigits; @ml = Algorithm::CheckDigits->method_list(); %md = Algorithm::CheckDigits->method_descriptions(); $isbn = CheckDigits('ISBN'); if ($isbn->is_valid('3-930673-48-7')) { # do something } $cn = $isbn->complete('3-930673-48'); # $cn = '3-930673-48-7' $cd = $isbn->checkdigit('3-930673-48-7'); # $cd = '7' $bn = $isbn->basenumber('3-930673-48-7'); # $bn = '3-930673-48' =head1 ABSTRACT This module provides a number of methods to test and generate check digits. For more information have a look at the web site F (german). =head1 SUBROUTINES/METHODS =head2 CheckDigits($method) Returns an object of an appropriate Algorithm::CheckDigits class for the given algorithm. Dies with an error message if called with an unknown algorithm. See below for the available algorithms. Every object understands the following methods: =over 4 =item is_valid($number) Returns true or false if C<$number> contains/contains no valid check digit. =item complete($number) Returns a string representation of C<$number> completed with the appropriate check digit. =item checkdigit($number) Extracts the check digit from C<$number> if C<$number> contains a valid check digit. =item basenumber($number) Extracts the basenumber from C<$number> if C<$number> contains a valid check digit. =back =head2 Algorithm::CheckDigits::plug_in($module, $description, $prefkey) Register a module that provides the same four methods as above. This function returns a handle with which the registered module can be instantiated. The first argument C<$module> is the module to be used for this plugin. This argument is mandatory. Do not register 'Algorithm::CheckDigits'. The second argument is a short description of the algorithm. If it is omitted, the string C will be taken. The third argument is the preferred key for this algorithm. The C function does not guarantee to register the algorithm with this key. Instead it returns the key under which the algorithm is registered. See L for more information on registering plugins. =head2 Algorithm::CheckDigits::method_list() Returns a list of known methods for check digit computation. =head2 Algorithm::CheckDigits::method_descriptions() Returns a hash of descriptions for the known methods for check digit computations. The keys of the hash are the values returned by C. =head2 Algorithm::CheckDigits::print_methods() Returns a list of known methods for check digit computation. You may use the following to find out which methods your version of Algorithm::CheckDigits provides and where to look for further information. perl -MAlgorithm::CheckDigits -e Algorithm::CheckDigits::print_methods =head2 CHECK SUM METHODS At the moment these methods to compute check digits are provided: (vatrn - VAT Return Number, in german ustid UmsatzSTeuer-ID) =over 4 =item euronote European bank notes, see L. =item amex, bahncard, diners, discover, enroute, eurocard, happydigits, isin, jcb, klubkarstadt, mastercard, miles&more, visa, imei, imeisv See L. =item siren, siret See L. =item ismn See L. =item ean, iln, isbn13, nve, 2aus5 See L. =item identcode_dp, leitcode_dp See L. =item rentenversicherung See L. =item sedol See L. =item betriebsnummer See L. =item postscheckkonti See L. =item ups See L. =item hkid, isbn, issn, nhs_gb, ustid_pt, vat_sl, wagonnr_br See L. =item pzn See L. =item pkz See L. =item cpf, titulo_eleitor See L. =item ccc_es See L. =item ustid_fi, vatrn_fi See L. =item ustid_dk, vatrn_dk See L. =item nric_sg See L. =item ahv_ch See L. =item ustid_nl, vatrn_nl See L. =item bwpk_de See L. =item ustid_gr, vatrn_gr See L. =item esr5_ch See L. =item ustid_pl, vatrn_pl See L. =item ecno, ec-no, einecs, elincs See L. =item isan See L. =item dni_es See L. =item ustid_ie, vatrn_ie See L. =item code_39 See L. =item ustid_lu, vatrn_lu See L. =item ustid_be, vatrn_be See L. =item iban See L. =item upc See L. =item blutbeutel, bzue_de, ustid_de, vatrn_de See L. =item sici See L. =item pa_de See L. =item cas See L. =item dem Old german bank notes (DEM), see L. =item ustid_at, vatrn_at See L. =item esr9_ch See L. =item verhoeff Verhoeff scheme, see L or L =back =head2 EXPORT This module exports the Function C that is used to create an instance of a checker with the given algorithm. =head1 REGISTERING PLUGINS Brian T. Wightman was the first, asking me to add a plugin registry to Algorithm::CheckDigits and so I added the function C that does just this, registering plug in modules to be used just like the modules in the distribution of this module. Providing some means to add additional algorithms without the need to change the module has the benefit that the user of those additional algorithms may easily use them with the same interface as the other algorithms without having to wait for a new version, that may or may not include the wanted algorithm. But there is a problem: the user must be able to select the new algorithms like he did with the other ones. And the catch is: since these new algorithms are developed independently there is no guarantee that no more than one module applies for the same handle. I could have implemented some simple strategies like last one wins (the module that registers last for a given handle is the one that is choosen) or first one wins (the first registered module is choosen). Instead I went for something more complex to assure that every module that wants to get registered will be registered and that every registered module will be accessible by the same handle as long as the program runs. To make this work C sees the third argument only as a hint how the handle should look like, when a module is registered. It returns the real handle with which the algorithm can be instantiated. That means a developer of a plugin module cannot make the handle immediately available like I did for the modules in the distribution. Instead there should be something like a public variable or function that returns the handle as it came back from the C function. This could go like this in the module: package Algorithm::XyZ; use Algorithm::CheckDigits; our $xyz = Algorithm::CheckDigits::plug_in('Algorithm::XyZ', 'XyZ check digits', 'xyz'); And the user of this algorithm would write something like this: use Algorithm::CheckDigits; use Algorithm::XyZ; my $cd = CheckDigits($Algorithm::XyZ::xyz); if ($cd->is_valid($some_number)) { # do something } Please have a look at the plugin tests in the test directory (I) and the accompanying modules (I) for example usage. You may also try to load an additional module with the scripts in I and I and look for the additional algorithms in the output: perl -Ilib -It -MPluginLibA bin/checkdigits.pl list perl -Ilib -It -MPluginLibA cgi-bin/checkdigits.cgi =head2 Namespace I would like to ask you to use any namespace below or outside but not direct Algorithm::CheckDigits. That means for instance for the XyZ algorithm, Algorithm::XyZ would be fine, Algorithm::CheckDigits::Plugin::XyZ or Algorithm::CheckDigits::X::XyZ would be fine too. But Algorithm::CheckDigits::XyZ could collide with some future version of the Algorithm::CheckDigits distribution, so please avoid this namespace. =head1 SEE ALSO L, F. =head1 BUGS AND LIMITATIONS The function C dies if you try to register the module 'Algorithm::CheckDigits'. Please report any bugs or feature requests to C, or through the web interface at L. =head1 AUTHOR Mathias Weidner, C<< mamawe@cpan.org >> =head1 THANKS Petri Oksanen made me aware that CheckDigits('IMEI') would invoke no test at all since there was no entry for this in the methods hash. Brian T. Wightman made me think about and implement the plugin interface. =head1 COPYRIGHT AND LICENSE Copyright 2004-2020 by Mathias Weidner This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits000755001750001750 014144705550 23135 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M07_001.pm000444001750001750 517714144705550 24565 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M07_001; use 5.006; use strict; use warnings; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $class = ref($proto) || $proto; return bless({}, $class); } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9]*)([0-9])$/) { return ($2 == _compute_checkdigit($1)); } return 0; } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([0-9]*)$/) { return $number . _compute_checkdigit($1); } return undef; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9]*)([0-9])$/) { return $1 if ($2 == _compute_checkdigit($1)); } return undef; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9]*)([0-9])$/) { return $2 if ($2 == _compute_checkdigit($1)); } return undef; } # checkdigit() sub _compute_checkdigit { my $number = shift; my @digits = split(//,$number); my $even = 0; my $sum = 0; foreach my $digit (@digits) { $sum += $digit; $sum += $digit if ($even); $even = not $even; } return $sum % 7; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M07_001 - compute check digits modulo 7 method 1 =head1 SYNOPSIS use Algorithm::CheckDigits; $m001 = CheckDigits('m001'); if ($m001->is_valid('1234567892')) { # do something } $cn = $m001->complete('123456789'); # $cn = '1234567892' $cd = $m001->checkdigit('1234567892'); # $cd = '2' $bn = $m001->basenumber('1234567892'); # $bn = '123456789' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1. All digits are added. =item 2. All digits at even positions are added. =item 3. The sum of step 1 and 2 is taken modulo 7. =item 4. This is the check digit. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or undef if C<$number> does not consist solely of digits. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return undef otherwise. =item checkdigit($number) Returns the check digit belonging to C<$number> or undef if C<$number> does not consist solely of digits. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M09_001.pm000444001750001750 564514144705550 24567 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M09_001; use 5.006; use strict; use warnings; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $class = ref($proto) || $proto; return bless({}, $class); } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([A-Za-z][0-9]{10})([0-9])$/) { return $2 == _compute_checkdigit($1); } return 0; } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[A-Za-z][0-9]{10}$/) { return $number . _compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([A-Za-z][0-9]{10})([0-9])$/) { return $1 if ($2 == _compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([A-Za-z][0-9]{10})([0-9])$/) { return $2 if ($2 == _compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $number = shift; if ($number =~ /^([A-Za-z])([0-9]{10})$/) { my @nums = (); my $sum = 0; push(@nums,ord(uc($1)) - ord('A') +1); push(@nums,split(//,$2)); foreach my $num (@nums) { $sum += $num; } return 8 - ($sum % 9); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M09_001 - compute check digits for Euro notes =head1 SYNOPSIS use Algorithm::CheckDigits; $euro = CheckDigits('euronote'); if ($euro->is_valid('X07738250357')) { # do something } $cn = $euro->complete('X0773825035'); # $cn = 'X07738250357' $cd = $euro->checkdigit('X07738250357'); # $cd = '7' $bn = $euro->basenumber('X07738250357'); # $bn = 'X0773825035' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Letters are replaced with their position in the alphabet ('A' = 1, ...). =item 2 The total of the digits of all numbers is computed. =item 3 This sum is taken modulo 9. =item 4 The check digit is the difference between 8 and the number of step 3. =back To validate the last digit of the total of the digits of all numbers inclusive check digit must be 8. =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_001.pm000444001750001750 1350414144705550 24570 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 si et: package Algorithm::CheckDigits::M10_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = qv('v1.3.6'); our @ISA = qw(Algorithm::CheckDigits); my %prefix = ( 'amex' => [ '34', '37', ], 'bahncard' => [ '70', ], 'diners' => [ '30[0-5]', '36', '38', ], 'discover' => [ '6011', ], 'enroute' => [ '2014', '2149', ], 'jcb' => [ '1800', '2131', '3088', ], 'mastercard' => [ '5[1-5]', ], 'miles&more' => [ '99', '22', ], 'visa' => [ '4', ], ); my %ctable = ( '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, ); # Aliases $prefix{'eurocard'} = $prefix{'mastercard'}; # omit prefixes doesn't work with the test numbers my %omitprefix = ( 'jcb' => 0, 'enroute' => 0, 'discover' => 0, ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); $self->_determine_pattern(); return $self; } # new() sub is_valid { my ( $self, $number ) = @_; if ( $number =~ /^($self->{pattern})([0-9])$/i ) { return $2 == $self->_compute_checkdigit( uc($1) ); } return ''; } # is_valid() sub complete { my ( $self, $number ) = @_; if ( $number =~ /^$self->{pattern}$/i ) { return $number . $self->_compute_checkdigit( uc($number) ); } return ''; } # complete() sub basenumber { my ( $self, $number ) = @_; if ( $number =~ /^($self->{pattern})([0-9])$/i ) { return $1 if ( $2 == $self->_compute_checkdigit( uc($1) ) ); } return ''; } # basenumber() sub checkdigit { my ( $self, $number ) = @_; if ( $number =~ /^($self->{pattern})([0-9])$/i ) { return $2 if ( $2 == $self->_compute_checkdigit( uc($1) ) ); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/\s//g; if ( $omitprefix{ $self->{type} } ) { my $pf = $prefix{ $self->{type} }; for my $p ( @{$pf} ) { if ( $number =~ /^$p([0-9]+)$/ ) { $number = $1; last; } } } if ('isin' eq $self->{type}) { # With ISIN letters are handled differently than for instance with # CUSIP, so we substitute them here $number =~ s/([A-Z])/$ctable{$1}/ge; } elsif ('imeisv' eq $self->{type}) { # With IMEISV the SV (software version) is left out from the # computation of the checkdigit $number = substr( $number, 0, 14 ) if ( 'imeisv' eq $self->{type} ); } my @digits = map { $ctable{$_} } split( //, $number ); my $even = 1; my $sum = 0; for ( my $i = $#digits; $i >= 0; $i-- ) { if ($even) { my $tmp = 2 * $digits[$i]; $sum += $tmp / 10 + $tmp % 10; } else { $sum += $digits[$i] / 10 + $digits[$i] % 10; } $even = not $even; } return ( 10 - $sum % 10 ) % 10; } # _compute_checkdigit() sub _determine_pattern { my $self = shift; if ('cusip' eq $self->{type}) { $self->{pattern} = qr/[0-9A-Z]{8}/io; } else { $self->{pattern} = qr/[0-9A-Z ]+/io; } } # _determine_pattern() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_001 - compute check digits for Bahncard (DE), IMEI, IMEISV, ISIN, Miles&More, Payback (DE), Personnummer (SE), Passport (BR), Credit Cards, SSN (US), Samordningsnummer (SE), VAT RN (ES), VAT RN (IT), VAT RN (SE), International Securities Identifikation Number (ISIN), CUSIP =head1 SYNOPSIS use Algorithm::CheckDigits; $visa = CheckDigits('visa'); if ($visa->is_valid('4111 1111 1111 1111')) { # do something } $cn = $visa->complete('4111 1111 1111 111'); # $cn = '4111 1111 1111 1111' $cd = $visa->checkdigit('4111 1111 1111 1111'); # $cd = '7' $bn = $visa->basenumber('4111 1111 1111 1111'); # $bn = '4111 1111 1111 111' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all numbers are weighted alternatively 1 and 2 (that is the check digit is weighted 1). =item 2 The total of the digits of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3. =back To validate the total of the digits of all numbers inclusive check digit taken modulo 10 must be 0. =head2 METHODS =over 4 =item is_valid($number) Returns true only if the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, If the checked number is of type CUSIP, the number must be exact 9 digits or letters long and must not have spaces in between. =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. F For IMEI, IMEISV: ETSI Technical Specification TS 100 508 (v6.2.0) =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_002.pm000444001750001750 623514144705550 24554 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_002; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[0-9 ]*$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/\s//g; if ($number =~ /^([0-9]*)$/) { my @digits = split(//,$number); my $even = 1; my $sum = 0; for (my $i = $#digits; $i >= 0; $i--) { if ($even) { my $tmp = 2 * $digits[$i]; $sum += $tmp / 10 + $tmp % 10; } else { $sum += $digits[$i]; } $even = not $even; } return (10 - $sum % 10) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_002 - compute check digits for CINS (US), SIREN (FR), SIRET (FR) =head1 SYNOPSIS use Algorithm::CheckDigits; $siret = CheckDigits('siret'); if ($siret->is_valid('73282932000074')) { # do something } $cn = $siret->complete('7328293200007'); # $cn = '73282932000074' $cd = $siret->checkdigit('73282932000074'); # $cd = '4' $bn = $siret->basenumber('73282932000074'); # $bn = '7328293200007' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all numbers are weighted alternatively 1 and 2. =item 2 The total of the digits of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_003.pm000444001750001750 606014144705550 24551 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_003; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^M([0-9-]*)([0-9])$/i) { return ($2 == $self->_compute_checkdigit($1)); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^M([0-9-]*[0-9])(-*)$/i) { return "M$1" . '-' . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^M([0-9-]*[0-9])(-*)([0-9])$/i) { return "M$1" if ($self->is_valid($number)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^M([0-9-]*)([0-9])$/i) { return $2 if ($self->is_valid($number)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/-//g; if ($number =~ /^([0-9]*)$/) { my @digits = split(//,$number); my $even = 0; my $sum = 9; for (my $i = 0; $i <= $#digits; $i++) { if ($even) { $sum += 3 * $digits[$i]; } else { $sum += $digits[$i]; } $even = not $even; } return (10 - ($sum % 10) % 10); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_003 - compute check digits for ISMN =head1 SYNOPSIS use Algorithm::CheckDigits; $ismn = CheckDigits('ismn'); if ($ismn->is_valid('M-345-24680-5')) { # do something } $cn = $ismn->complete('M-345-24680'); # $cn = 'M-345-24680-5' $cd = $ismn->checkdigit('M-345-24680-5'); # $cd = '5' $bn = $ismn->basenumber('M-345-24680-5'); # $bn = 'M-345-24680' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The 'M' as the first number gets the value 3. Beginning left all numbers are weighted alternatively 3 and 1. =item 2 The sum of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_004.pm000444001750001750 1023614144705550 24572 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_004; # vim: set tw=78 sw=4 ts=4 si sr et: use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my $valid_prefix = { isbn13 => { 978 => 1, 979 => 1, }, issn13 => { 977 => 1, }, }; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ( $self, $number ) = @_; if ( $number =~ /^([0-9 -]+)([0-9])$/ ) { return $2 == $self->_compute_checkdigit($1); } return ''; } # is_valid() sub complete { my ( $self, $number ) = @_; if ( $number =~ /^[0-9 -]+$/ ) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ( $self, $number ) = @_; if ( $number =~ /^([0-9 -]+)([0-9])$/ ) { return $1 if ( $2 == $self->_compute_checkdigit($1) ); } return ''; } # basenumber() sub checkdigit { my ( $self, $number ) = @_; if ( $number =~ /^([0-9 -]+)([0-9])$/ ) { return $2 if ( $2 == $self->_compute_checkdigit($1) ); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/[ -]//g; if ( $number =~ /^([0-9]*)$/ ) { if ( $valid_prefix->{ $self->{type} } ) { my $prefix = substr $number, 0, 3; unless ( $valid_prefix->{ $self->{type} }->{$prefix} ) { return -1; } } my @digits = split( //, $number ); my $even = 1; my $sum = 0; for ( my $i = $#digits; $i >= 0; $i-- ) { if ($even) { $sum += 3 * $digits[$i]; } else { $sum += $digits[$i]; } $even = not $even; } return ( 10 - $sum % 10 ) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_004 - compute check digits for 2aus5, EAN, ILN, ISBN13, NVE =head1 SYNOPSIS use Algorithm::CheckDigits; $ean = CheckDigits('ean'); if ($ean->is_valid('7622200004607')) { # do something } $cn = $ean->complete('762220000460'); # $cn = '7622200004607' $cd = $ean->checkdigit('7622200004607'); # $cd = '7' $bn = $ean->basenumber('7622200004607'); # $bn = '762220000460' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all numbers are weighted alternatively 1 and 3 (that is the check digit is weighted 1). =item 2 The sum of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3. =back To validate the total of the digits of all numbers inclusive check digit taken modulo 10 must be 0. =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of digits, spaces and hyphen and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits, spaces and hyphen. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 BUGS AND LIMITATIONS When invoked as C the module checks whether the first three digits (the country code) are 978 or 979, the current (as of 2006) EAN country codes for books. If at any time other EAN country codes for ISBN-13 will be specified and the then responsible maintainer ignores this in the code, please send a friendly email. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_005.pm000444001750001750 606714144705550 24562 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_005; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9 .]{11,})([0-9])$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[0-9 .]{11,}$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9 .]{11,})([0-9])$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9 .]{11,})([0-9])$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/[.\s]//g; if ($number =~ /^([0-9]{11})$/) { my @digits = split(//,$number); my $even = 0; my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { if ($even) { $sum += 9 * $digits[$i]; } else { $sum += 4 * $digits[$i]; } $even = not $even; } return (10 - $sum % 10) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_005 - compute check digits for Deutsche Post Identcode/Leitcode (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $ic = CheckDigits('identcode_dp'); if ($ic->is_valid('21.802 580.906 6')) { # do something } $cn = $ic->complete('21.802 580.906'); # $cn = '21.802 580.9066' $cd = $ic->checkdigit('21.802 580.906 6'); # $cd = '6' $bn = $ic->basenumber('21.802 580.906 6'); # $bn = '21.802 580.906' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left all numbers are weighted alternatively 4 and 9. =item 2 The sum of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_006.pm000444001750001750 624014144705550 24554 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_006; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 2,1,2,5,7,1,2,1,2,1,2,1 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{8}[A-Za-z]\d\d)(\d)$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^\d{8}[A-Za-z]\d\d$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{8}[A-Za-z]\d\d)(\d)$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{8}[A-Za-z]\d\d)(\d)$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^(\d{8})([A-Za-z])(\d\d)$/) { my $lv = sprintf("%2.2d",ord(uc($2)) - ord('A') + 1); my @digits = split(//,"$1$lv$3"); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { my $tmp = $weight[$i] * $digits[$i]; $sum += $tmp / 10; $sum += $tmp % 10 } return $sum % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_006 - compute check digits for Rentenversicherung (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $rv = CheckDigits('rentenversicherung'); if ($rv->is_valid('65180539W001')) { # do something } $cn = $rv->complete('65180539W00'); # $cn = '65180539W001' $cd = $rv->checkdigit('65180539W001'); # $cd = '1' $bn = $rv->basenumber('65180539W001'); # $bn = '65180539W00' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The letter is replaced with a two-figure number appropriate to the position of the letter in the german alphabet. =item 2 Beginning left all numbers are weighted with 2,1,2,5,7,1,2,1,2,1,2,1. =item 3 The the total of the digits of all products is computed. =item 4 The check digit is sum from step 3 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_008.pm000444001750001750 1010314144705550 24567 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_008; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = qv('v1.3.6'); our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 1,3,1,7,3,9,1 ); my $value = 0; my %ctable = map { $_, $value++ } ( '0'..'9', 'A'..'Z' ); my $re_alpha = qr/[B-DF-HJ-NP-TV-Z]/; my $re_alnum = qr/[0-9B-DF-HJ-NP-TV-Z]/; my $re_sedol = qr/(\d{6}|$re_alpha$re_alnum{5})(\d)?/; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my $self = shift; my $number = uc shift; if ($number =~ /^$re_sedol$/o) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my $self = shift; my $number = uc shift; if ($number =~ /^$re_sedol$/o) { return $number . $self->_compute_checkdigit($number); } else { return ''; } } # complete() sub basenumber { my $self = shift; my $number = uc shift; if ($number =~ /^$re_sedol$/o) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my $self = shift; my $number = uc shift; if ($number =~ /^$re_sedol$/o) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my @digits = map { $ctable{$_} } split(//,$number); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } return (10 - ($sum % 10)) % 10; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_008 - compute check digits for Sedol (GB) =head1 SYNOPSIS use Algorithm::CheckDigits; $sedol = CheckDigits('sedol'); if ($sedol->is_valid('0123457')) { # do something } $cn = $sedol->complete('012345'); # $cn = '0123457' $cd = $sedol->checkdigit('0123457'); # $cd = '7' $bn = $sedol->basenumber('0123457'); # $bn = '012345' =head1 DESCRIPTION Prior to March 2004 SEDOL codes solely consisted of numbers. Since March 2004 SEDOL codes are a 7 character alphanumeric code. The structure of the alphanumeric SEDOL codes is one alpha character followed by 5 alphanumeric characters followed by the numerical check digit. =over 4 =item Alpha characters are B-Z excluding vowels. =item Alphanumerical characters are 0-9, B-Z excluding vowels. =item Numerical Characters are 0-9. =back No SEDOL code will be issued without the first alpha character. Active numerical SEDOL codes issued prior to March 2004 remain valid. =head2 ALGORITHM =over 4 =item S<0> All characters are assigned a numerical value from 0 to 35 where the characters '0' to '9' get 0 to 9, 'B' to 'Z' get 11 to 35 with the position of the vowels kept empty (for instance 'D' gets 13, 'F' gets 15). =item S<1> Beginning left all numbers are weighted with 1,3,1,7,3,9 and 1 (checkdigit) =item S<2> The sum of all products is computed. =item S<3> The check digit is the difference of the sum from step 3 to the next multiple of 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. This function always returns the SEDOL code in upper case. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. This function always returns the SEDOL base number in upper case. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F Masterfile technical specifications V7.0. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_009.pm000444001750001750 645514144705550 24567 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_009; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { my $cd = $self->_compute_checkdigit($1); return ($2 == $cd || $2 == ((5 + $cd) % 10)); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[0-9 ]*$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { return $1 if ($self->is_valid($number)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9 ]*)([0-9])$/) { return $2 if ($self->is_valid($number)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/\s//g; if ($number =~ /^([0-9]*)$/) { my @digits = split(//,$number); my $even = 0; my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { if ($even) { my $tmp = 2 * $digits[$i]; $sum += $tmp / 10 + $tmp % 10; } else { $sum += $digits[$i]; } $even = not $even; } return $sum % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_009 - compute check digits for Betriebsnummer (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $betrnr = CheckDigits('betriebsnummer'); if ($betrnr->is_valid('73282932000074')) { # do something } $cn = $betrnr->complete('7328293200007'); # $cn = '73282932000074' $cd = $betrnr->checkdigit('73282932000074'); # $cd = '4' $bn = $betrnr->basenumber('73282932000074'); # $bn = '7328293200007' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left all numbers are weighted alternatively 1 and 2. =item 2 The total of the digits of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3 taken modulo 10. HINT: The last digit of the 'Betriebsnummer' may be the check digit or the last digit of the sum of the constant 5 and the check digit. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_010.pm000444001750001750 617714144705550 24560 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_010; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @items = ( 0,9,4,6,8,2,7,1,3,5 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d\d-?\d{8})-?(\d)$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^\d\d-?\d{8}-?$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d\d-?\d{8}-?)(\d)$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d\d-?\d{8})-?(\d)$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^\d\d-?\d{8}-?$/) { $number =~ s/-//g; my @digits = split(//,$number); my $sum = 0; my $cf = 0; for (my $i = 0; $i <= $#digits; $i++) { $cf = $items[($digits[$i] + $cf) % 10]; } return (10 - $cf) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_010 - compute check digits for Postscheckkonti (CH) =head1 SYNOPSIS use Algorithm::CheckDigits; $pck = CheckDigits('postcheckkonti'); if ($pck->is_valid('85-12345678-7')) { # do something } $cn = $pck->complete('85-12345678'); # $cn = '85-12345678-7' $cd = $pck->checkdigit('85-12345678-7'); # $cd = '7' $bn = $pck->basenumber('85-12345678-7'); # $bn = '85-12345678' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The sequence of digits is processed left to right. For the first digit we assume a carry forward of 0. =item 2 For each digit d(i) the carry forward cf(i) is the digit at the the position p in the sequence ( 0, 9, 4, 6, 8, 2, 7, 1, 3, 5 ), where p is (d(i) + cf(i-1)) modulo 10. =item 3 The check digit is the difference of the sum from step 3 to the next multiple of 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M10_011.pm000444001750001750 602714144705550 24553 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M10_011; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.*)([0-9])$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; my $cd = $self->_compute_checkdigit($number); if ($cd != -1) { return $number . $cd; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.*)([0-9])$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.*)([0-9])$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/\s//g; $number =~ s/^1z//i; $number =~ y/A-Za-z/2-90-90-72-90-90-7/; if ($number =~ /^([0-9]*)$/) { my @digits = split(//,$number); my $even = 0; my $sum = 0; foreach my $digit (@digits) { $sum += $digit; $sum += $digit if ($even); $even = not $even; } return (10 - $sum % 10) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M10_011 - compute check digits UPS (US) =head1 SYNOPSIS use Algorithm::CheckDigits; $ups = CheckDigits('ups'); if ($ups->is_valid('1Z 591580 68 55587736')) { # do something } $cn = $ups->complete('1Z 591580 68 5558773'); # $cn = '1Z 591580 68 55587736' $cd = $ups->checkdigit('1Z 591580 68 55587736'); # $cd = '6' $bn = $ups->basenumber('1Z 591580 68 55587736'); # $bn = '1Z 591580 68 5558773' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left all numbers are weighted alternatively 1 and 2. =item 2 The sum of all products is computed. =item 3 The sum of step 3 ist taken modulo 10. =item 4 The check digit is the difference between 10 and the number from step 3. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_001.pm000444001750001750 1067214144705550 24574 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my $cd = { 'isbn' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'X', 0 ], 'ustid_pt' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0 ], 'hkid' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 0 ], 'wagonnr_br' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 ], 'nhs_gb' => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0 ], 'vat_sl' => [ 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 0, -1 ], # ? }; $cd->{'issn'} = $cd->{'isbn'}; $cd->{'vatrn_pt'} = $cd->{'ustid_pt'}; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return uc($2) eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[-0-9A-Za-z]+$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^[-0-9A-Za-z]+$/) { $number =~ s/-//g; my @digits = split(//,$number); my $sum = 0; my $weight = 2; for (my $i = $#digits; $i >= 0; $i--) { $digits[$i] = 1 + ord(uc($digits[$i])) - ord('A') if ($digits[$i] =~ /[A-Z]/i); $sum += $weight * $digits[$i]; ++$weight; } $sum %= 11; return $cd->{$self->{type}}[11-$sum] if ($cd->{$self->{type}}); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_001 - compute check digits for ISBN, ISSN, VAT RN (PT), HKID (HK), Wagon number (BR), NHS (GB), VAT (SL) =head1 SYNOPSIS use Algorithm::CheckDigits; $isbn = CheckDigits('isbn'); if ($isbn->is_valid('3-88229-192-3')) { # do something } $cn = $isbn->complete('3-88229-192-'); # $cn = '3-88229-192-3' $cd = $isbn->checkdigit('3-88229-192-3'); # $cd = '3' $bn = $isbn->basenumber('3-88229-192-3'); # $bn = '3-88229-192-' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The sequence of digits is processed right to left. Every digit is multiplied with their position in the sequence (i.e. the digit left to the check digit has the weight 2 then 3 etc.). With a Hongkong ID (hkid) the leftmost char is replaced with its position in the alphabet and then multiplied with 8 (its weight). =item 2 The sum of all products is computed. =item 3 The sum of step 2 is taken modulo 11. =item 4 The checkdigit is the difference of the sum from step 3 to eleven under the following conditions: =over 8 =item isbn,issn If the difference is 10, the check digit is 'X'. If the difference is 11, the check digit is 0. =item ustid_pt If the difference is greater then 9, the check digit is '0'. =item hkid If the difference is 10, the check digit is 'A'. If the difference is 11, the check digit is 0. =item wagonnr_br If the difference is 10, the check digit is 0. If the difference is 11, the check digit is 1. =item nhs_gb If the difference is 10, the number would not be taken. If the difference is 11, the check digit is 0. =item vat_sl This is a little bit unclear, don't trust on the method for this type. =back =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_002.pm000444001750001750 572414144705550 24557 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_002; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return uc($2) eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[0-9]+$/) { my $cd = $self->_compute_checkdigit($number); return $number . $cd unless 0 > $cd; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^[-0-9]+$/) { $number =~ s/-//g; my @digits = split(//,$number); my $sum = 0; my $weight = 2; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight * $digits[$i]; ++$weight; } $sum %= 11; return 10 == $sum ? -1 : $sum; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_002 - compute check digits for PZN (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $pzn = CheckDigits('pzn'); if ($pzn->is_valid('4877800')) { # do something } $cn = $pzn->complete('487780'); # $cn = '4877800' $cd = $pzn->checkdigit('4877800'); # $cd = '0' $bn = $pzn->basenumber('4877800'); # $bn = '487780' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 From left to right beginning with the first position all digits are multiplied with 2,3,4,... =item 2 The sum of all products is computed. =item 3 The checkdigit ist the sum of step 2 taken modulo 11. =item 4 If the checkdigit is '10' the whole number is not taken as a PZN. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_003.pm000444001750001750 663314144705550 24560 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_003; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 4,2,1,6,3,7,9,10,5,8,4,2 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{11})(\d)$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^\d{11}$/) { my $cd = $self->_compute_checkdigit($number); return 0 > $cd ? '' : $number . $cd; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{11})(\d)$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{11})(\d)$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^\d{11}$/) { my @digits = split(//,$number); my $sum = 0; my $cf = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; for (my $i = 0; $i <= 9; $i++) { return $i if (10 == ($sum + $weight[11] * $i) % 11); } } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_003 - compute check digits for PKZ (GDR) =head1 SYNOPSIS use Algorithm::CheckDigits; $pkz = CheckDigits('pkz'); if ($pkz->is_valid('150765400354')) { # do something } $cn = $pkz->complete('15076540035'); # $cn = '150765400354' $cd = $pkz->checkdigit('150765400354'); # $cd = '4' $bn = $pkz->basenumber('150765400354'); # $bn = '150765400354' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The checkdigit is set to 0. =item 2 From right to left the digits are weighted (multiplied) with 2,4,8,5,10,9,7,3,6,1,2,4. =item 3 The products are added. =item 4 The sum of step 3 is taken modulo 11. =item 5 The value of step 4 is added to a multiple (0..9) of the weight of the checkdigit (2). =item 6 The sum of step 5 is taken modulo 11. =item 7 The checkdigit is the multiple of the weight of the checkdigit where the value of step 6 equals 10. =item 8 If there can't be reached a value of 10 in step 6, the number cannot be taken as a PKZ. =back To validate a PKZ apply steps 2 to 4 to the complete number. =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_004.pm000444001750001750 711514144705550 24555 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_004; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([-\d.]+)(\d\d)$/) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[-\d.]+$/) { my $cd = $self->_compute_checkdigit($number); return $number . $cd unless 0 > $cd; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([-\d.]+)(\d\d)$/) { return $1 if ($2 eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([-\d.]+)(\d\d)$/) { return $2 if ($2 eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my ($cd1,$cd2) = ('',''); my $calc_cd = sub { my $number = shift; my $weight = shift; my @digits = split(//,$number); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight * $digits[$i]; --$weight; }; $sum %= 11; return 0 if (2 > $sum); return 11 - $sum; }; return -1 unless ($number =~ /^[-\d.]+$/); $number =~ s/[-.]//g; if ('cpf' eq $self->{type}) { return -1 unless length($number) == 9; $cd1 = $calc_cd->($number,10); $cd2 = $calc_cd->($number . $cd1,11); } elsif ('titulo_eleitor' eq $self->{type}) { $number = substr("00000000000" . $number, -10); $cd1 = $calc_cd->(substr($number,0,8),9); $cd2 = $calc_cd->(substr($number,-2) . $cd1,4); } return $cd1 . $cd2; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =encoding iso-8859-1 =head1 NAME CheckDigits::M11_004 - compute check digits for CPF (BR), Título Eleitoral (BR) =head1 SYNOPSIS use Algorithm::CheckDigits; $cpf = CheckDigits('cpf'); if ($cpf->is_valid('043.033.407-90')) { # do something } $cn = $cpf->complete('043.033.407-'); # $cn = '043.033.407-90' $cd = $cpf->checkdigit('043.033.407-90'); # $cd = '90' $bn = $cpf->basenumber('043.033.407-90'); # $bn = '043.033.407-' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 From left to right all digits are multiplied with their position in the sequence. =item 2 The sum of all products is computed. =item 3 The sum of step 2 is taken modulo 11. a) If the result is 0 or 1 the checkdigit is 0 b) otherwise the checkdigit is 11 minus the result. =item 4 The first checkdigit is appended to the number and step 1 to 3 are repeated. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_006.pm000444001750001750 660014144705550 24555 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_006; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{4}-?\d{4})-?(\d\d)-?(\d{10})$/) { return uc($2) eq $self->_compute_checkdigits($1,$3); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{4}-?\d{4})[-\s]+(\d{10})$/) { return "$1-" . $self->_compute_checkdigits($1,$2) . "-$2"; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{4}-?\d{4})-?(\d\d)-?(\d{10})$/) { return "$1- -$3" if ($2 eq $self->_compute_checkdigits($1,$3)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{4}-?\d{4})-?(\d\d)-?(\d{10})$/) { return $2 if ($2 eq $self->_compute_checkdigits($1,$3)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $bank = shift; my $account = shift; $bank =~ s/-//g; my $calc = sub { my @digits = split(//,shift); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$#digits - $i]; } $sum %= 11; return $sum ? 11 - $sum : 0; }; my $first = $calc->($bank); my $second = $calc->($account); return sprintf("%d%d",$first,$second); } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =encoding iso-8859-1 =head1 NAME CheckDigits::M11_006 - compute check digits for Código de Cuenta Corriente (ES) =head1 SYNOPSIS use Algorithm::CheckDigits; $ccc = CheckDigits('ccc_es'); if ($ccc->is_valid('2420-0730-27-0050103552')) { # do something } $cn = $ccc->complete('2420-0730- -0050103552'); # $cn = '2420-0730-27-0050103552' $cd = $ccc->checkdigit('2420-0730-27-0050103552'); # $cd = '27' $bn = $ccc->basenumber('2420-0730-27-0050103552'); # $bn = '2420-0730- -0050103552'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all digits are weighted 6,3,7,9,10,5,8,4,2,1. =item 2 The weighted digits are added. =item 3 The sum of step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3. If the difference is 10, the checkdigit is 1. If the difference is 11, the checkdigit is 0. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and hyphens and the two digits in the middle are valid check digits according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and inserted into the middle of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits, hyphens and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_007.pm000444001750001750 571114144705550 24560 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_007; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 7, 9, 10, 5, 8, 4, 2 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{7})(\d)$/) { return uc($2) eq $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{7})$/) { return "$1" . $self->_compute_checkdigits($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{7})(\d)$/) { return $1 if ($2 eq $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{7})(\d)$/) { return $2 if ($2 eq $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my @digits = split(//,shift); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; return $sum ? ($sum == 1 ? '' : 11 - $sum) : 0; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_007 - compute check digits for VAT Registration Number (FI) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_fi'); if ($ustid->is_valid('13669598')) { # do something } $cn = $ustid->complete('1366959'); # $cn = '13669598' $cd = $ustid->checkdigit('13669598'); # $cd = '8' $bn = $ustid->basenumber('13669598'); # $bn = '1366959'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left every digit is weighted with 7,9,10,5,8,4,2. =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3. Is the difference 10, the number won't be taken. If the difference is 11, the checkdigit is 0. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of digits and the rightmost digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and appended to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F (german) =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_008.pm000444001750001750 530214144705550 24555 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_008; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 2, 7, 6, 5, 4, 3, 2, 1 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{8})$/) { return 0 == $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; return "$1" if( $number =~ /^(\d{8})$/ and 0 == $self->_compute_checkdigits($1)); return ''; } # complete() sub basenumber { my ($self,$number) = @_; return "$1" if( $number =~ /^(\d{8})$/ and 0 == $self->_compute_checkdigits($1)); return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; return '' if( $number =~ /^(\d{8})$/ and 0 == $self->_compute_checkdigits($1)); return undef; } # checkdigit() sub _compute_checkdigits { my $self = shift; my @digits = split(//,shift); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; return $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_008 - compute check digits for VAT Registration Number (DK) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_dk'); if ($ustid->is_valid('13585628')) { # do something } $cn = $ustid->complete('1358562'); # $cn = '13585628' $cd = $ustid->checkdigit('13585628'); # $cd = '8' $bn = $ustid->basenumber('13585628'); # $bn = '1358562'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left every digit is weighted with 2, 7, 6, 5, 4, 3, 2, 1 =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The number is valid if the sum from step 3 is zero (0). =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the sum computed according to the algorithm given above is 0. Returns false otherwise, =item complete($number) Returns C<$number> if C<$number> is valid according to the algorithm given above. Return '' otherwise. =item basenumber($number) Returns C<$number> if C<$number> is valid according to the algorithm given above. Return '' otherwise. =item checkdigit($number) Returns '' if C<$number> is valid. Return undef otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_009.pm000444001750001750 613614144705550 24564 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_009; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 2, 7, 6, 5, 4, 3, 2 ); my @keys = ('', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'Z', 'J' ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([fgst])?(\d{7})([a-jz])$/i) { return (uc($3) eq $self->_compute_checkdigits($2)); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if($number =~ /^([fgst])?(\d{7})$/i) { my $prefix = $1 || ''; return $prefix . $2 . $self->_compute_checkdigits($2); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if( $number =~ /^([fgst])?(\d{7})([a-jz])$/i and uc($3) eq $self->_compute_checkdigits($2)) { my $prefix = $1 || ''; return $prefix . $2; } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([fgst])?(\d{7})([a-jz])$/i) { return $self->_compute_checkdigits($2); } return undef; } # checkdigit() sub _compute_checkdigits { my $self = shift; my @digits = split(//,shift); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; return $keys[11 - $sum]; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_009 - compute check digits NRIC (SG) =head1 SYNOPSIS use Algorithm::CheckDigits; $nric = CheckDigits('nric_sg'); if ($nric->is_valid('S1234567D')) { # do something } $cn = $nric->complete('S1234567'); # $cn = 'S1234567D' $cd = $nric->checkdigit('S1234567D'); # $cd = 'D' $bn = $nric->basenumber('S1234567D'); # $bn = 'S1234567'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left every digit is weighted with 2, 7, 6, 5, 4, 3, 2 =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3 converted to a character according to the following table: @cd = ('','A','B','C','D','E','F','G','H','I','Z','J', ); =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists of seven digits (optional preceded by a letter out of 'F', 'G', 'S', 'T') followed by a valid letter according to the algorithm given above. Returns false otherwise, =item complete($number) The check letter for C<$number> is computed and appended to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and letters. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns '' if C<$number> is valid. Return undef otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_010.pm000444001750001750 577514144705550 24564 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_010; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9.]+)(\d)$/) { return $2 == $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([0-9.]+)$/) { return "$1" . $self->_compute_checkdigits($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9.]+)(\d)$/) { return $1 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9.]+)(\d)$/) { return $2 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $number = shift; $number =~ s/\.//g; my @digits = split(//,$number); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; return $sum == 0 ? 0 : ($sum == 1 ? '' : 11 - $sum); } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_010 - compute check digits AHV number (CH) =head1 SYNOPSIS use Algorithm::CheckDigits; $ahv = CheckDigits('ahv_ch'); if ($ahv->is_valid('123.45.678.113')) { # do something } $cn = $ahv->complete('123.45.678.11'); # $cn = '123.45.678.113' $cd = $ahv->checkdigit('123.45.678.113'); # $cd = '3' $bn = $ahv->basenumber('123.45.678.113'); # $bn = '123.45.678.11'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left every digit is weighted with 5,4,3,2,7,6,5,4,3,2. =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3. Is the difference 10, the number won't be taken. If the difference is 11, the checkdigit is 0. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and dots and the rightmost digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and appended the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and dots. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_011.pm000444001750001750 763614144705550 24563 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_011; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)(B\d\d)?$/i) { return $2 == $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(?:.(B\d\d))?$/ and (my $cd = $self->_compute_checkdigits($1)) ne '') { my $tail = $2 || ''; return $1 . $cd . $tail; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)(B\d\d)?$/i) { my $tail = $3 ? ".$3" : ''; return $1 . $tail if ($2 == $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)(B\d\d)?$/) { return $2 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $number = shift; $number =~ s/\.//g; my @digits = split(//,$number); my $len = scalar(@digits) + 1; my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += ($len - $i) * $digits[$i]; } $sum %= 11; return ($sum == 10) ? '' : $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_011 - compute check digits for VAT Registration Number (NL) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_nl'); if ($ustid->is_valid('123456782')) { # do something } if ($ustid->is_valid('123456782B04')) { # do something } $cn = $ustid->complete('12345678'); # $cn = '123456782' $cn = $ustid->complete('12345678.B04'); # $cn = '123456782B04' $cd = $ustid->checkdigit('123456782'); # $cd = '2' $cd = $ustid->checkdigit('123456782B04'); # $cd = '2' $bn = $ustid->basenumber('123456782'); # $bn = '12345678'; $bn = $ustid->basenumber('123456782B04'); # $bn = '12345678.B04'; =head1 DESCRIPTION This VATRN has 12 "digits", the third last must be a I, the fourth last is the checkdigit. I don't know anything about the meaning of the last two digits. You may use the whole VATRN or only the first eight digits to compute the checkdigit with this module. =head2 ALGORITHM =over 4 =item 1 Beginning right with the digit before the checkdigit all digits are weighted with their position. I.e. the digit before the checkdigit is multiplied with 2, the next with 3 and so on. =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 If the sum from step 3 is 10, the number is discarded. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if the first eight positions of C<$number> consist solely of digits (maybe followed by 'B' and to further digits) and the eighth digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and inserted at position eight of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits a dot and maybe 'B' at the ninth position. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 SEE ALSO L, L, F, =head1 AUTHOR Mathias Weidner, C<< >> =head1 COPYRIGHT AND LICENSE Copyright 2004-2020 by Mathias Weidner This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_012.pm000444001750001750 743014144705550 24554 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_012; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 2,3,4,5,6,7,1,6,7,2,3 ); my %table_to = ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, A => 12, B => 14, C => 16, D => 18, E => 20, F => 22, G => 24, H => 26, I => 28, J => 6, K => 8, L => 10, M => 12, N => 14, O => 16, P => 18, Q => 20, R => 22, S => 4, T => 6, U => 8, V => 10, W => 12, X => 14, Y => 16, Z => 18, ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([-0-9a-z]+)(\d)$/i) { return $2 == $self->_compute_checkdigits($1); } return undef; } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([-0-9a-z]+)$/i and (my $cd = $self->_compute_checkdigits($1)) ne '') { return $1 . $cd; } return undef; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([-0-9a-z]+)(\d)$/i) { return $1 if ($2 == $self->_compute_checkdigits($1)); } return undef; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([-0-9a-z]+)(\d)$/i) { return $2 if ($2 == $self->_compute_checkdigits($1)); } return undef; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $number = shift; $number =~ s/-//g; my @digits = split(//,$number); my $len = scalar(@digits) + 1; my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $table_to{uc($digits[$i])}; } $sum %= 11; return ($sum == 0) ? 1 : ($sum == 1) ? 0 : 11 - $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_012 - compute check digits for Bundeswehrpersonenkennnummer (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $bwpk = CheckDigits('bwpk_de'); if ($bwpk->is_valid('151058-D-20711')) { # do something } $cn = $bwpk->complete('151058-D-2071'); # $cn = '151058-D-20711' $cd = $bwpk->checkdigit('151058-D-20711'); # $cd = '1' $bn = $bwpk->basenumber('151058-D-20711'); # $bn = '151058-D-2071'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left all digits are weighted 2,3,4,5,6,7,1,6,7,2,3. Letters are replaced according to the following table: my %table_to = ( A => 12, B => 14, C => 16, D => 18, E => 20, F => 22, G => 24, H => 26, I => 28, J => 6, K => 8, L => 10, M => 12, N => 14, O => 16, P => 18, Q => 20, R => 22, S => 4, T => 6, U => 8, V => 10, W => 12, X => 14, Y => 16, Z => 18, ); =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checksum is 11 minus the sum from step 3. If the difference is 10, the checkdigit is 0. If the difference is 11, the checkdigit is 1. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers, letters and hyphens and the rightmost digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and appended to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits, hyphens and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_013.pm000444001750001750 577714144705550 24571 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_013; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)$/) { return $2 == $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([0-9]+)$/ and (my $cd = $self->_compute_checkdigits($1)) ne '') { return $1 . $cd; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)$/) { return $1 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9]+)(\d)$/) { return $2 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $number = shift; my @digits = split(//,$number); my $len = scalar(@digits); my $sum = 0; for (my $i = $#digits; $i >= 0; $i--) { $sum += 2 ** ($len - $i) * $digits[$i]; } $sum %= 11; return ($sum > 9) ? 0 : $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_013 - compute check digits for VAT Registration Number (GR) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_gr'); if ($ustid->is_valid('123456783')) { # do something } $cn = $ustid->complete('12345678'); # $cn = '123456783' $cd = $ustid->checkdigit('123456783'); # $cd = '3' $bn = $ustid->basenumber('123456783'); # $bn = '12345678'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right with the digit before the checkdigit all digits are weighted with 2 ** position. I. e. the last digit is multiplied with 2, the next with 4, then 8 and so on. =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 If the sum from step 3 is greater than 9, the check sum is 0 else it is the sum itself. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the rightmost digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and appended to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_015.pm000444001750001750 637714144705550 24570 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_015; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 2, 3, 4, 5, 6, 7 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d\d)([\d ]+)$/) { return $1 == $self->_compute_checkdigits($2); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^([\d ]+)$/) { return $self->_compute_checkdigits($1) . $1; } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d\d)([\d ]+)$/) { return $2 if ($1 == $self->_compute_checkdigits($2)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d\d)([\d ]+)$/) { return $1 if ($1 == $self->_compute_checkdigits($2)); } return ''; } # checkdigit() sub _compute_checkdigits { my ($self,$number) = @_; $number =~ s/\s//g; my @digits = split(//,$number); my $sum = 0; for (my $i = $#digits; $i >= 0; $i--) { $sum += $weight[($#digits - $i) % 6] * $digits[$i]; } $sum %= 11; my $retval = (0 == $sum) ? '00' : sprintf("%02d",(11 - $sum)); $retval; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_015 - compute check digits for ESR5 (CH) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('esr5_ch'); if ($ustid->is_valid('050001000012000 241170032660178 10304')) { # do something } $cn = $ustid->complete('0001000012000 241170032660178 10304'); # $cn = '050001000012000 241170032660178 10304' $cd = $ustid->checkdigit('0001000012000 241170032660178 10304'); # $cd = '05' $bn = $ustid->basenumber('050001000012000 241170032660178 10304'); # $bn = '0001000012000 241170032660178 10304'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all digits are weighted with the repeating sequence 2, 3, 4, 5, 6, 7. =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3. If the difference is 11, the checkdigit is 00. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers (with or without space between them) and the first two digits are valid check digits according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and inserted before the C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits, spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F (german), F, page 52 (german) =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_016.pm000444001750001750 614314144705550 24560 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M11_016; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 6, 5, 7, 2, 3, 4, 5, 6, 7 ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{9})(\d)$/) { return $2 == $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{9})$/) { return "$1" . $self->_compute_checkdigits($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{9})(\d)$/) { return $1 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{9})(\d)$/) { return $2 if ($2 == $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my @digits = split(//,shift); my $sum = 0; for (my $i = 0; $i <= $#digits; $i++) { $sum += $weight[$i] * $digits[$i]; } $sum %= 11; return $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_016 - compute check digits vor VAT Registration Number (PL) =head1 SYNOPSIS use Algorithm::CheckDigits; $nip = CheckDigits('nip'); if ($nip->is_valid('8567346215')) { # do something } $cn = $nip->complete('856734621'); # $cn = '8567346215' $cd = $nip->checkdigit('856734621'); # $cd = '5' $bn = $nip->basenumber('8567346215'); # $bn = '856734621'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left every digit is weighted with 6, 5, 7, 2, 3, 4, 5, 6, 7 =item 2 The weighted digits are added. =item 3 The sum from step 2 is taken modulo 11. =item 4 The checkdigit is 11 minus the sum from step 3. Is the difference 10, the number won't be taken. If the difference is 11, the checkdigit is 0. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the rightmost digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and appended to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits, hyphens and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check digits of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, F (German), F (English), F (Polish) =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M11_017.pm000444001750001750 615714144705550 24566 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 si et: package Algorithm::CheckDigits::M11_017; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ( $self, $number ) = @_; if ( $number =~ /^([-\d]+)(\d)$/ ) { return $2 eq $self->_compute_checkdigit($1); } return ''; } # is_valid() sub complete { my ( $self, $number ) = @_; if ( $number =~ /^[-\d]+$/ ) { my $cd = $self->_compute_checkdigit($number); return $number . $cd unless 0 > $cd; } return ''; } # complete() sub basenumber { my ( $self, $number ) = @_; if ( $number =~ /^([-\d]+)(\d)$/ ) { return $1 if ( $2 eq $self->_compute_checkdigit($1) ); } return ''; } # basenumber() sub checkdigit { my ( $self, $number ) = @_; if ( $number =~ /^([-\d.]+)(\d)$/ ) { return $2 if ( $2 eq $self->_compute_checkdigit($1) ); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my ( $cd1, $cd2 ) = ( '', '' ); $number =~ s/[-]//g; my @digits = split //, $number; my $sum = 0; for ( my $i = 0; $i <= $#digits; $i++ ) { $sum += ( $i + 1 ) * $digits[$i]; } $sum %= 11; return 0 if ( 9 < $sum ); return $sum; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M11_017 - compute check digits for EC-No, EINECS, ELINCS =head1 SYNOPSIS use Algorithm::CheckDigits; $ecno = CheckDigits('ecno'); if ($ecno->is_valid('200-236-6')) { # do something } $cn = $ecno->complete('200-236-'); # $cn = '200-236-6' $cd = $ecno->checkdigit('200-236-6'); # $cd = '6' $bn = $ecno->basenumber('200-236-6'); # $bn = '200-236-' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 From left to right all digits are multiplied with their position in the sequence. =item 2 The sum of all products is computed. =item 3 The sum of step 2 is taken modulo 11. The checkdigit is the last digit of the result. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M16_001.pm000444001750001750 630414144705550 24556 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M16_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([0-9a-f]{15})([0-9a-f])$/i) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[0-9a-f]{15}$/i) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([0-9a-f]{15})([0-9a-f])$/i) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([0-9a-f]{15})([0-9a-f])$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^[0-9a-f]{15}$/i) { my ($a,$b,$c); my @digits = split(//,$number); $a = 16; for (my $i = 0; $i <= $#digits; $i++) { $b = ($a % 17) + hex($digits[$i]); $c = $b % 16; $c = 16 unless ($c); $a = 2 * $c; } return sprintf("%X",(17 - ($a % 17)) % 16); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M16_001 - compute check digits for ISAN =head1 SYNOPSIS use Algorithm::CheckDigits; $isan = CheckDigits('isan'); if ($isan->is_valid('123A567B8912E01A')) { # do something } $cn = $isan->complete('123A567B8912E01'); # $cn = '123A567B8912E01A' $cd = $isan->checkdigit('123A567B8912E01A'); # $cd = '4' $bn = $isan->basenumber('123A567B8912E01A'); # $bn = '123A567B8912E01' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 C C, where C is the decimal value of the hexdigit at position I. C C, for I greater than 1 =item 2 Beginning left for each I = 1..16, C, C, C are computed. =item 3 The check digit is the value for C where C equals 1. =item 4 The check digit is appended as hexadecimal value to the number. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M23_001.pm000444001750001750 541314144705550 24554 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M23_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @keytable = ( 'T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E', ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{8})-?([A-HJ-NP-TV-Z])$/i) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{8})-?$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{8}-?)([A-HJ-NP-TV-Z])$/i) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{8})-?([A-HJ-NP-TV-Z])$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/-//g; if ($number =~ /^\d{8}$/i) { return $keytable[($number % 23)]; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M23_001 - compute check digits for DNI (ES) =head1 SYNOPSIS use Algorithm::CheckDigits; $dni = CheckDigits('dni_es'); if ($dni->is_valid('54362315K')) { # do something } $cn = $dni->complete('54362315'); # $cn = '54362315K' $cd = $dni->checkdigit('54362315K'); # $cd = 'K' $bn = $dni->basenumber('54362315K'); # $bn = '54362315' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The checkdigit is the whole number taken modulo 23 and coded according to a keytable. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M23_002.pm000444001750001750 766714144705550 24572 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M23_002; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @keytable = ( 'W', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{7})([A-W])([A-IW])?$/i) { return $2 eq $self->_compute_checkdigit($1,$3); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{7}).?([A-IW])?$/i) { return $1 . $self->_compute_checkdigit($1,$2) . ($2 || ''); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{7})([A-W])([A-IW])?$/i) { if (uc($2) eq $self->_compute_checkdigit($1,$3)) { return $3 ? "$1.$3" : $1; } } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{7})([A-W])([A-IW])?$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1,$3)); } return ''; } # checkdigit() sub _compute_checkdigit { my ($self, $number,$optional) = @_; my $sum = 0; my @digits = split(//,$number); for (my $i = 0; $i < 7; $i++) { $sum += $digits[$i] * (8-$i); } if ($optional and $optional =~ /[A-I]/i) { $sum += 9 * (ord($optional) - ord('A') + 1); } return $keytable[$sum % 23]; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M23_002 - compute check digits for Tax Identification Number (IE) =head1 SYNOPSIS use Algorithm::CheckDigits; $dni = CheckDigits('tin_ie'); if ($dni->is_valid('8473625E')) { # do something } $cn = $dni->complete('1234567.W'); # $cn = '1234567TW' $cd = $dni->checkdigit('1234577IA'); # $cd = 'I' $bn = $dni->basenumber('1234577WW'); # $bn = '1234577.W' =head1 DESCRIPTION =head2 ALGORITHM The irish TIN (Tax Identification Number) or VAT Regstration Number consists of 7 digits, a letter in the range from 'A' - 'W' as checksum, and an optionally letter in the range from 'A' - 'I' or the letter 'W'. =over 4 =item 1 In reverse order, each digit is multiplied by a weight started at 2. (i.e. the number left from the check digit is multiplied with 2, the next with 3 and so on). =item 2 If there is an optional letter following the checksum letter (position 9), this letter is mapped to a numeric value based on the following mapping: "A" = 1, "B" = 2, ... "H" = 8, "I" = 9. "W" or absence of this letter means a value of 0. This numeric value is multiplied with 9. =item 3 All products from step 1 and 2 are added. =item 4 The check digit is the sum from step 3 modulo 23. This number is expressed as the corresponding letter from the alphabet where A-V correspond to 1-22 and W stands for check digit 0. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> complies with the rules given above and there is a valid check digit at position eight. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and inserted at position eight of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and an optional letter at position nine. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. As a placeholder for the checksum a point ('.') is inserted at position eight when the checksum contains the optional letter at position nine. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M43_001.pm000444001750001750 635614144705550 24565 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M43_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my %keytable = ( '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, '-' => 36, '.' => 37, ' ' => 38, '$' => 39, '/' => 40, '+' => 41, '%' => 42, ); my %keymap = reverse %keytable; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/i) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(.*)$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/i) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my $sum = 0; my @digits = split(//,$number); for (my $i = 0; $i < length($number); $i++) { $sum += $keytable{$digits[$i]}; } $sum %= 43; return $keymap{$sum}; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M43_001 - compute check digits for Code-39 =head1 SYNOPSIS use Algorithm::CheckDigits; $c39 = CheckDigits('code_39'); if ($c39->is_valid('AB-123K')) { # do something } $cn = $c39->complete('AB-123'); # $cn = 'AB-123K' $cd = $c39->checkdigit('AB-123K'); # $cd = 'K' $bn = $c39->basenumber('AB-123K'); # $bn = 'AB-123' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 After replacing all non numeric letters with their respective values, the sum of all numbers is computers =item 2 The checkdigit is the sum from step 1 taken modulo 43. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M89_001.pm000444001750001750 531114144705550 24565 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M89_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my @keytable = ( 'T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E', ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{6})?(\d\d)$/i) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{6})$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{6})(\d\d)$/i) { return $1 if ($2 eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{6})(\d\d)$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^\d{6}$/i) { return sprintf("%2.2d",($number % 89)); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M89_001 - compute check digits for VAT Registration Number (LU) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_lu'); if ($ustid->is_valid('13669580')) { # do something } $cn = $ustid->complete('136695'); # $cn = '13669580' $cd = $ustid->checkdigit('13669580'); # $cd = '80' $bn = $ustid->basenumber('13669580'); # $bn = '136695' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The checksum is the whole number taken modulo 89. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M97_001.pm000444001750001750 574214144705550 24574 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M97_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(?:BE)?(\d{7,8})?(\d\d)$/i) { return $2 eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(?:BE)?(\d{7,8})$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(?:BE)?(\d{7,8})(\d\d)$/i) { return $1 if ($2 eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(?:BE)?(\d{7,8})(\d\d)$/i) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^\d{7,8}$/i) { return sprintf("%2.2d",97 - ($number % 97)); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M97_001 - compute check digits for VAT Registration Number (BE) =head1 SYNOPSIS use Algorithm::CheckDigits; $ustid = CheckDigits('ustid_be'); if ($ustid->is_valid('136695962')) { # do something } $cn = $ustid->complete('1366959'); # $cn = '136695962' $cd = $ustid->checkdigit('136695962'); # $cd = '62' $bn = $ustid->basenumber('136695962'); # $bn = '1366959' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 The whole number (without checksum) is taken modulo 97. =item 2 The checksum is difference of the remainder from step 1 to 97. =back =head2 METHODS =over 4 =item is_valid($number) Returns true if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. A leading 'BE' before the numbers will be ignored. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. A leading 'BE' before the digits is ignored for the computation and retained for the result. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. A leading 'BE' before the digits will be ignored and not returned with the result. Return '' otherwise. =item checkdigit($number) Returns the checkdigits of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, L. L =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/M97_002.pm000444001750001750 1133314144705550 24606 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::M97_002; # vim: set sw=4 ts=4 tw=78 et si: use 5.006; use strict; use warnings; use integer; use version; our $VERSION = qv('v1.3.6'); our @ISA = qw(Algorithm::CheckDigits); my %subst = ( A => 10, B => 11, C => 12, D => 13, E => 14, F => 15, G => 16, H => 17, I => 18, J => 19, K => 20, L => 21, M => 22, N => 23, O => 24, P => 25, Q => 26, R => 27, S => 28, T => 29, U => 30, V => 31, W => 32, X => 33, Y => 34, Z => 35, ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my $self = shift; if (my ($checkdigit,$number) = _prepare_number(shift)) { return $checkdigit eq _compute_checkdigit($number); } return '' } # is_valid() sub complete { my $self = shift; my $incomplete = uc(shift); if (my ($checkdigit,$number) = _prepare_number($incomplete)) { $incomplete =~ /^(..)..(.+)/; return $1 . _compute_checkdigit($number) . $2; } return ''; } # complete() sub basenumber { my $self = shift; my $unchecked = shift; if (my ($checkdigit,$number) = _prepare_number($unchecked)) { $unchecked =~ /^(..)..(.+)/; return $1.'00'.$2 if ($checkdigit eq _compute_checkdigit($number)); } return ''; } # basenumber() sub checkdigit { my $self = shift; if (my ($checkdigit,$number) = _prepare_number(shift)) { return $checkdigit if ($checkdigit eq _compute_checkdigit($number)); } return ''; } # checkdigit() sub _compute_checkdigit { my $number = shift; # my $bignum = Math::BigInt->new($number); # my $mod = $bignum % 97; # # A comparison with Benchmark::compthese() brought: # # Rate bignum 9_digits # bignum 2502/s -- -95% # 9_digits 46225/s 1748% -- # # so I reverted _compute_checkdigit to this code. # Thanks to Detlef Pilzecker for making me aware of this. my $mod = ''; while ($number ne '') { $number = $mod . $number; $mod = substr($number,0,9,'') % 97; } return sprintf("%02d",(98 - $mod)); } # _compute_checkdigit() sub _prepare_number { my $number = uc(shift); $number =~ s/\s//g; if ($number =~ /^([A-Z]{2})(\d\d)([A-Z\d]{2,30})$/) { my $checkdigit = $2; $number = $3 . $1 . '00'; $number =~ s/([A-Z])/$subst{$1}/g; return ($checkdigit,$number); } return; } # _prepare_number() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::M97_002 - compute check digits for International Bank Account Number (IBAN) =head1 SYNOPSIS use Algorithm::CheckDigits; $iban = CheckDigits('iban'); if ($iban->is_valid('DE88 2008 0000 09703 7570 0')) { # do something } $cn = $iban->complete('DE00 2008 0000 09703 7570 0'); # $cn = 'DE88 2008 0000 09703 7570 0' $cd = $iban->checkdigit('DE88 2008 0000 09703 7570 0'); # $cd = '88' $bn = $iban->basenumber('DE88 2008 0000 09703 7570 0'); # $bn = 'DE00 2008 0000 09703 7570 0' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item S<0> The IBAN number must be prepared. The first two letters and the checksum will be moved to the right end. The letters are substituted according to the substitute table and the checksum is set to '00'. =item S<1> The whole number is taken modulo 97. =item S<2> The checksum is difference between 98 and the result of step 1. =item S<3> If the checksum is smaller then 10, a leading zero will be prepended. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigits of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS Detlef Pilzecker pointed out to me that there may be more letters as the first two in an IBAN number. He also made me aware of a faster method to compute the check number than using Math::BigInt. =head1 SEE ALSO L, L, F, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MBase_001.pm000444001750001750 636414144705550 25210 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MBase_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^\d+$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^\d+$/) { my @digits = split(//,$number); my $sum = 0; my $even = 0; for (my $i = 0; $i <= $#digits; $i++) { if ($even) { $sum += $digits[$i]; } else { $sum += 3 * $digits[$i]; } $even = not $even; } return (10 - ($sum % 10)) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MBase_001 - compute check digits for UPC (US) =head1 SYNOPSIS use Algorithm::CheckDigits; $rv = CheckDigits('upc'); if ($rv->is_valid('012345678905')) { # do something } $cn = $rv->complete('01234567890'); # $cn = '012345678905' $cd = $rv->checkdigit('012345678905'); # $cd = '5' $bn = $rv->basenumber('012345678905'); # $bn = '01234567890' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Add all digits in odd-numbered positions. =item 2 Multiply the sum from step 1 with 3. =item 3 Add all digits in even-numbered positions. =item 4 Add the product from step 2 and the sum from step 3. =item 5 If the sum from step 4 is 0 modulo 10, the check digit is 0. Else the check digit is 10 minus the sum from step 4 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS Aaron W. West pointed me to a fault in the computing of the check digit. =head1 SEE ALSO L, L, F, F, F, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MBase_002.pm000444001750001750 610214144705550 25177 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MBase_002; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return uc($2) eq $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[ 0-9]+$/) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $1 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.+)(.)$/) { return $2 if (uc($2) eq $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; if ($number =~ /^[ 0-9]+$/) { $number =~ s/ //g; my @digits = split(//,$number); my $sum = 0; my $prod = 10; for (my $i = 0; $i <= $#digits; $i++) { $sum = (($prod + $digits[$i]) % 10) || 10; $prod = (2 * $sum) % 11; } return (11 - $prod) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =encoding iso-8859-1 =head1 NAME CheckDigits::MBase_002 - compute check digits for blood bags (DE), BZÜ (DE), VAT Registration Number (DE) =head1 SYNOPSIS use Algorithm::CheckDigits; $bb = CheckDigits('blutbeutel'); if ($bb->is_valid('2761011234567893')) { # do something } $cn = $bb->complete('276101123456789'); # $cn = '2761011234567893' $cd = $bb->checkdigit('2761011234567893'); # $cd = '3' $bn = $bb->basenumber('2761011234567893'); # $bn = '276101123456789'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Start with values P = 10, S = 0. =item 2 Beginning left you do the following for all digits =over 4 =item 1 S = (P + digit) modulo 10 =item 2 If S is 0 then S = 10. =item 3 P = (2 * S) modulo 11 =back =item 3 The check digit is (11 - P) modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MBase_003.pm000444001750001750 1032314144705550 25220 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MBase_003; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = qv('v1.3.6'); our @ISA = qw(Algorithm::CheckDigits); my @weight = ( 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ); my %table_to = ( '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, ); my @table_from = ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#', ); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/) { return uc($2) eq $self->_compute_checkdigits($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(.*)$/) { return "$1" . $self->_compute_checkdigits($1) } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/) { return "$1" if ($2 eq $self->_compute_checkdigits($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(.*)(.)$/) { return $2 if ($2 eq $self->_compute_checkdigits($1)); } return ''; } # checkdigit() sub _compute_checkdigits { my $self = shift; my $number = shift; my $digit; my @digits = split(//,$number); my $even = 0; my $sum1 = 0; my $sum2 = 0; for (my $i = $#digits; $i>= 0; $i--) { if (uc($digits[$i]) =~ /[0-9A-Z]/) { $digit = $table_to{uc($digits[$i])}; } else { $digit = 36; } $sum1 += 3 * $digit unless ($even); $sum2 += $digit if ($even); $even = not $even; } my $sum = 37 - (($sum1 + $sum2) % 37); return $table_from[$sum]; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MBase_003 - compute check digits for SICI (Serial Item and Contribution Identifier) =head1 SYNOPSIS use Algorithm::CheckDigits; $sici = CheckDigits('sici'); if ($sici->is_valid('0784-8679(20040308)6:<138>2.0.TX;2-H')) { # do something } $cn = $sici->complete('0784-8679(20040308)6:<138>2.0.TX;2-'); # $cn = '0784-8679(20040308)6:<138>2.0.TX;2-H' $cd = $sici->checkdigit('0784-8679(20040308)6:<138>2.0.TX;2-H'); # $cd = 'H' $bn = $sici->basenumber('0784-8679(20040308)6:<138>2.0.TX;2-H'); # $bn = '0784-8679(20040308)6:<138>2.0.TX;2-'; =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item S<0> In the string describing the number all letters (A-Z) are replaced with numbers 10-35 accordingly. All other non-numbers are replaced by 36. =item S<1> Beginning right the numbers at all odd positions are added. =item S<2> The sum from step 1 is multiplied by 3. =item S<3> Beginning right the numbers at all even positions are added. =item S<4> The sums from step 2 and 3 are added. =item S<5> The sum from step 4 is taken modulo 37. =item S<6> The checksum is 37 minus the sum from step 5 where numbers from 10 to 35 are represented by 'A' to 'Z' accordingly and 36 is represented by '#'. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if the last letter is a valid check letter according to the algorithm given above. Returns false otherwise, =item complete($number) The check letter for C<$number> is computed and appended the end of C<$number>. Returns the complete number with check letter or ''. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the check letter of C<$number> if C<$number> has valid check digits. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F, F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_001.pm000444001750001750 1256214144705550 24712 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MXX_001; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my %weight = ( 'aba_rn' => [ 3,7,1,3,7,1,3,7,1, ], 'mxx-001' => [ 7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1, ], 'pa_de' => [ 7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1,7,3,1, ], ); sub new { my ($proto, $type) = @_; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); $self->{weight} = $weight{$type}; if ('aba_rn' eq $type) { $self->{complement} = 1; } return $self; } # new() sub is_valid { my ($self,$number) = @_; if ('aba_rn' eq $self->{type}) { $number =~ y/[0-9]//cd; if ($number =~ /^(\d{8})(\d)$/) { my $ccd = $self->_compute($1); my $pcd = $2; return 1 if ($ccd == $pcd); } } else { if ($number =~ /^\d{9}(\d).<+\d{6}(\d)<+\d{6}(\d)<+(\d)$/) { my @cd = $self->_compute_checkdigit($number); return 1 if ( $cd[0] == $1 and $cd[1] == $2 and $cd[2] == $3 and $cd[3] == $4 ); } elsif ($number =~ /^(\d+)(\d)$/) { return 1 if $2 == $self->_compute($1); } } return 0; } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{9}).(.<+\d{6}).(<+\d{6}).(<+).$/) { my @cd = $self->_compute_checkdigit($number); return $1 . $cd[0] . $2 . $cd[1] . $3 . $cd[2] . $4 . $cd[3]; } elsif ($number =~ /^(\d+)$/) { return $number . $self->_compute($number); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{9})(\d)(.<+\d{6})(\d)(<+\d{6})(\d)(<+)(\d)$/) { my @cd = $self->_compute_checkdigit($number); return $1 . '_' . $3 . '_' . $5 . '_' . $7 . '_' if ( $cd[0] == $2 and $cd[1] == $4 and $cd[2] == $6 and $cd[3] == $8 ); } elsif ($number =~ /^(\d+)(\d)$/) { return $1 if $2 == $self->_compute($1); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^\d{9}(\d).<+\d{6}(\d)<+\d{6}(\d)<+(\d)$/) { my @cd = $self->_compute_checkdigit($number); return join('<',@cd) if ( $cd[0] == $1 and $cd[1] == $2 and $cd[2] == $3 and $cd[3] == $4 ); } elsif ($number =~ /^(\d+)(\d)$/) { return $self->_compute($1); } return ''; } # checkdigit() sub _compute { my ($self,$digits) = @_; my ($sum,$i) = (0,0); my @w = @{$self->{weight}}; while ($digits =~ /(\d)/g) { $sum += $1 * $w[$i++]; } if ($self->{complement}) { return (10 - $sum % 10) % 10; } return $sum % 10; } # _compute() sub _compute_checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{9})..<+(\d{6}).<+(\d{6}).<+.$/) { my @cd; $cd[0] = $self->_compute($1); $cd[1] = $self->_compute($2); $cd[2] = $self->_compute($3); $cd[3] = $self->_compute($1 . $cd[0] . $2 . $cd[1] . $3 . $cd[2]); return @cd; } return (); } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MXX_001 - compute check digits for german Personalausweis (pa_de) or ABA routing numbers (aba_rn) =head1 SYNOPSIS use Algorithm::CheckDigits; $pa = CheckDigits('pa_de'); if ($pa->is_valid('2406055684D<<6810203<0705109<6')) { # do something } if ($pa->is_valid('2406055684') { # do_something } $cn = $pa->complete('240605568_D<<681020_<070510_<_'); # $cn = '2406055684D<<6810203<0705109<6' $cd = $pa->checkdigit('2406055684D<<6810203<0705109<6'); # $cd = '6' $bn = $pa->basenumber('2406055684D<<6810203<0705109<6'); # $bn = '240605568_D<<681020_<070510_<_' $aba = CheckDigits('aba_rn'); if ($aba->is_valid('789456124')) { # do something } =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning left all digits are weighted with 7,3,1,7,3,1,... for I or 3,7,1,3,7,1,3,7,1 for I. =item 2 The sum of those products is computed. =item 3 For I the checksum is the last digit of the sum from step 2 (modulo 10). For I the checksum is the difference of the sum from step 2 to the next multiple of 10. =item 4 For the german Personalausweis step 1 to 3 is performed for every part of the number and for all 3 parts including the particular checkdigit to compute the total checksum. If the number solely consists of digits, the checksum is just computed once according to algorithm given above. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS Aaron W. West pointed me to a fault in the computing of the check digit. Jim Hickstein made me aware of the ABA routing numbers. =head1 SEE ALSO L, L, F, F, F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_002.pm000444001750001750 652414144705550 24674 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 et si: package Algorithm::CheckDigits::MXX_002; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ( $self, $number ) = @_; if ( $number =~ /^(\d{1,7}-?\d{2}-?)(\d)$/ ) { return 1 if ( $2 == $self->_compute_checkdigit($1) ); } return ''; } # is_valid() sub complete { my ( $self, $number ) = @_; if ( $number =~ /^\d{1,7}-?\d{2}-?$/ ) { return $number . $self->_compute_checkdigit($number); } return ''; } # complete() sub basenumber { my ( $self, $number ) = @_; if ( $number =~ /^(\d{1,7}-?\d{2}-?)(\d)$/ ) { return $1 if ( $2 == $self->_compute_checkdigit($1) ); } return ''; } # basenumber() sub checkdigit { my ( $self, $number ) = @_; if ( $number =~ /^(\d{1,7}-?\d{2}-?)(\d)$/ ) { return $2 if ( $2 == $self->_compute_checkdigit($1) ); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/-//g; my @digits = split( //, $number ); my $weight = 1; my $sum = 0; for ( my $i = $#digits; $i >= 0; $i-- ) { $sum += $digits[$i] * $weight++; } return $sum % 10; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MXX_002 - compute check digits for CAS =head1 SYNOPSIS use Algorithm::CheckDigits; $cas = CheckDigits('cas'); if ($cas->is_valid('1333-74-0')) { # do something } $cn = $cas->complete('1333-74-'); # $cn = '1333-74-0' $cd = $cas->checkdigit('1333-74-0'); # $cd = '0' $bn = $cas->basenumber('1333-74-0'); # $bn = '1333-74-' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right with the second digit all digits are weighted ascending starting with 1. =item 2 The sum of those products is computed. =item 3 The checksum is the last digit of the sum from step 2 (modulo 10). =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS Aaron W. West pointed me to a fault in the computing of the check digit. HERMIER Christophe made me aware that CAS is now assigning 10-digit CAS Registry Numbers (F) =head1 SEE ALSO L, L, F, F F =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_003.pm000444001750001750 1032414144705550 24706 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MXX_003; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = qv('v1.3.6'); our @ISA = qw(Algorithm::CheckDigits); my $perm = [ [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], [ 9, 4, 5, 3, 1, 2, 6, 8, 7, 0, ], [ 4, 2, 8, 6, 5, 7, 3, 9, 0, 1, ], [ 2, 7, 9, 3, 8, 0, 6, 4, 1, 5, ], [ 7, 0, 4, 6, 9, 1, 3, 2, 5, 8, ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ], [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], ]; my $dieder = [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ], [ 1, 2, 3, 4, 0, 6, 7, 8, 9, 5, ], [ 2, 3, 4, 0, 1, 7, 8, 9, 5, 6, ], [ 3, 4, 0, 1, 2, 8, 9, 5, 6, 7, ], [ 4, 0, 1, 2, 3, 9, 5, 6, 7, 8, ], [ 5, 9, 8, 7, 6, 0, 4, 3, 2, 1, ], [ 6, 5, 9, 8, 7, 1, 0, 4, 3, 2, ], [ 7, 6, 5, 6, 8, 2, 1, 0, 4, 3, ], [ 8, 7, 6, 5, 9, 3, 2, 1, 0, 4, ], [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ], ]; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { return 1 if ($2 == $self->_compute_checkdigit(uc($1))); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^[ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ]$/i) { return $number . $self->_compute_checkdigit(uc($number)); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { return $1 if ($2 == $self->_compute_checkdigit(uc($1))); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^([ADGKLNSUYZ]{2}\d{7}[ADGKLNSUYZ])(\d)$/i) { return $2 if ($2 == $self->_compute_checkdigit(uc($1))); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ tr/ADGKLNSUYZ/0-9/; my @digits = split(//,$number); my $p0 = $perm->[0]->[$digits[0]]; my $rd = $p0; for (my $i = 1; $i <= $#digits; $i++) { my $pi = $perm->[$i % 8]->[$digits[$i]]; $rd = $dieder->[$rd]->[$pi]; } for (my $j = 0; $j <= 9; $j++) { return $j unless($dieder->[$rd]->[$j]); } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =encoding iso-8859-1 =head1 NAME CheckDigits::MXX_003 - compute check digits for DEM =head1 SYNOPSIS use Algorithm::CheckDigits; $dem = CheckDigits('dem'); if ($dem->is_valid('GD0645027K1')) { # do something } $cn = $dem->complete('GD0645027K'); # $cn = 'GD0645027K1' $cd = $dem->checkdigit('GD0645027K1'); # $cd = '1' $bn = $dem->basenumber('GD0645027K1'); # $bn = 'GD0645027K' =head1 DESCRIPTION =head2 ALGORITHM The algorithm is a variation of the Verhoeff scheme. =over 4 =item S<0> All letters are changed to numbers. =item S<1> All digits are permutated according to a permutation table. =item S<2> The permutated digits are combined using a diëder table. The first with the second, the result with the third, this result with the fourth and so on. =item S<3> The result of the last combination in the diëder table is in such a way combined that the result is 0 (zero). The number used for this combination is the checksum. =back For details look at the source. =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS =head1 SEE ALSO L, L, F, =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_004.pm000444001750001750 607214144705550 24674 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MXX_004; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(?:AT)?U?(\d{7})(\d)$/i) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(?:AT)?U?(\d{7})$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(AT)?(U)?(\d{7})(\d)$/i) { my $cc = $1 || ''; my $u = $2 || ''; return $cc.$u.$3 if ($4 == $self->_compute_checkdigit($3)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(?:AT)?U?(\d{7})(\d)$/i) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; $number =~ s/\s//g; if ($number =~ /^\d{7}$/) { my @digits = split(//,$number); my $even = 1; my $sum = 0; for (my $i = $#digits;$i >= 0;$i--) { if ($even) { $sum += $digits[$i]; } else { my $tmp = 2 * $digits[$i]; $sum += $tmp / 10 + $tmp % 10; } $even = not $even; } return (96 - $sum) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MXX_004 - compute check digits for VAT RN (AT) =head1 SYNOPSIS use Algorithm::CheckDigits; $vat = CheckDigits('ustid_at'); if ($vat->is_valid('U13585627')) { # do something } $cn = $vat->complete('U1358562'); # $cn = 'U13585627' $cd = $vat->checkdigit('U13585627'); # $cd = '7' $bn = $vat->basenumber('U13585627'); # $bn = 'U1358562' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Beginning right all numbers before the check digit are weighted alternatively 1 and 2. =item 2 The total of the digits of all products is computed and then subtracted from 96. =item 3 The check digit is the sum of step 3 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_005.pm000444001750001750 645614144705550 24703 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MXX_005; use 5.006; use strict; use warnings; use integer; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); my $ctable = [ [ 0, 9, 4, 6, 8, 2, 7, 1, 3, 5, 0, ], [ 9, 4, 6, 8, 2, 7, 1, 3, 5, 0, 9, ], [ 4, 6, 8, 2, 7, 1, 3, 5, 0, 9, 8, ], [ 6, 8, 2, 7, 1, 3, 5, 0, 9, 4, 7, ], [ 8, 2, 7, 1, 3, 5, 0, 9, 4, 6, 6, ], [ 2, 7, 1, 3, 5, 0, 9, 4, 6, 8, 5, ], [ 7, 1, 3, 5, 0, 9, 4, 6, 8, 2, 4, ], [ 1, 3, 5, 0, 9, 4, 6, 8, 2, 7, 3, ], [ 3, 5, 0, 9, 4, 6, 8, 2, 7, 1, 2, ], [ 5, 0, 9, 4, 6, 8, 2, 7, 1, 3, 1, ], ]; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d{8})(\d)$/i) { return $2 == $self->_compute_checkdigit($1); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^(\d{8})$/i) { return $number . $self->_compute_checkdigit($1); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d{8})(\d)$/i) { return $1 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d{8})(\d)$/i) { return $2 if ($2 == $self->_compute_checkdigit($1)); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my $carry = 0; if ($number =~ /^\d{8}$/) { my @digits = split(//,$number); for (my $i = 0;$i <= $#digits;$i++) { $carry = $ctable->[$carry]->[$digits[$i]]; } return (10 - $carry) % 10; } return -1; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =head1 NAME CheckDigits::MXX_005 - compute check digits for ESR9 (CH) =head1 SYNOPSIS use Algorithm::CheckDigits; $esr = CheckDigits('esr9'); if ($esr->is_valid('123456786')) { # do something } $cn = $esr->complete('12345678'); # $cn = '123456786' $cd = $esr->checkdigit('123456786'); # $cd = '6' $bn = $esr->basenumber('123456786'); # $bn = '12345678' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Digits are processed left to right. For the first digit applies the balance is 0. =item 2 The new balance is taken from the balance table according to the current balance (row) and the digit (column). =item 3 The check digit is the difference from the last balance to 10 taken modulo 10. =back =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits and spaces. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 SEE ALSO L, L, F. =cut Algorithm-CheckDigits-v1.3.6/lib/Algorithm/CheckDigits/MXX_006.pm000444001750001750 1054714144705550 24720 0ustar00mathiasmathias000000000000package Algorithm::CheckDigits::MXX_006; use 5.006; use strict; use warnings; use integer; use Data::Dumper; use version; our $VERSION = 'v1.3.6'; our @ISA = qw(Algorithm::CheckDigits); our @inverted = (0, 4, 3, 2, 1, 5, 6, 7, 8, 9 ); my $perm = [ [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], [ 9, 4, 5, 3, 1, 2, 6, 8, 7, 0, ], [ 4, 2, 8, 6, 5, 7, 3, 9, 0, 1, ], [ 2, 7, 9, 3, 8, 0, 6, 4, 1, 5, ], [ 7, 0, 4, 6, 9, 1, 3, 2, 5, 8, ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ], [ 1, 5, 7, 6, 2, 8, 3, 0, 9, 4, ], [ 5, 8, 0, 3, 7, 9, 6, 1, 4, 2, ], [ 8, 9, 1, 6, 0, 4, 3, 5, 2, 7, ], ]; my $dieder = [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ], [ 1, 2, 3, 4, 0, 6, 7, 8, 9, 5, ], [ 2, 3, 4, 0, 1, 7, 8, 9, 5, 6, ], [ 3, 4, 0, 1, 2, 8, 9, 5, 6, 7, ], [ 4, 0, 1, 2, 3, 9, 5, 6, 7, 8, ], [ 5, 9, 8, 7, 6, 0, 4, 3, 2, 1, ], [ 6, 5, 9, 8, 7, 1, 0, 4, 3, 2, ], [ 7, 6, 5, 6, 8, 2, 1, 0, 4, 3, ], [ 8, 7, 6, 5, 9, 3, 2, 1, 0, 4, ], [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ], ]; sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless({}, $class); $self->{type} = lc($type); return $self; } # new() sub is_valid { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/i) { return 1 if ($2 == $self->_compute_checkdigit(uc($1))); } return '' } # is_valid() sub complete { my ($self,$number) = @_; if ($number =~ /^\d+$/i) { return $number . $self->_compute_checkdigit(uc($number)); } return ''; } # complete() sub basenumber { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/i) { return $1 if ($2 == $self->_compute_checkdigit(uc($1))); } return ''; } # basenumber() sub checkdigit { my ($self,$number) = @_; if ($number =~ /^(\d+)(\d)$/i) { return $2 if ($2 == $self->_compute_checkdigit(uc($1))); } return ''; } # checkdigit() sub _compute_checkdigit { my $self = shift; my $number = shift; my $input = shift; my $c = 0; # initialize check at 0 my $digit = 0; my $i = 0; my $r; foreach $digit (reverse split(//, $number)) { # This was jonathans implementation, his permutation # table is offset by one compared to the one I already # took in MXX_003.pm and reused here # $c = $di->[$c]->[$f->[($i+1) % 8]->[$digit]]; $c = $dieder->[$c]->[$perm->[$i % 8]->[$digit]]; $i++; } return $inverted[$c]; } # _compute_checkdigit() # Preloaded methods go here. 1; __END__ =encoding iso-8859-1 =head1 NAME CheckDigits::MXX_006 - compute check digits with Verhoeff scheme =head1 SYNOPSIS use Algorithm::CheckDigits; $verhoeff = CheckDigits('verhoeff'); if ($verhoeff->is_valid('14567894')) { # do something } $cn = $verhoeff->complete('1456789'); # $cn = '14567894' $cd = $verhoeff->checkdigit('14567894'); # $cd = '4' $bn = $verhoeff->basenumber('14567894'); # $bn = '1456789' =head1 DESCRIPTION =head2 ALGORITHM =over 4 =item 1 Right to left all digits are permutated according to a permutation table. =item 2 The permutated digits are combined using a diëder table. The first with the second, the result with the third, this result with the fourth and so on. =item 3 The result of the last combination in the diëder table is in such a way combined that the result is 0 (zero). The number used for this combination is the checksum. =back For details look at the source. =head2 METHODS =over 4 =item is_valid($number) Returns true only if C<$number> consists solely of numbers and the last digit is a valid check digit according to the algorithm given above. Returns false otherwise, =item complete($number) The check digit for C<$number> is computed and concatenated to the end of C<$number>. Returns the complete number with check digit or '' if C<$number> does not consist solely of digits. =item basenumber($number) Returns the basenumber of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =item checkdigit($number) Returns the checkdigit of C<$number> if C<$number> has a valid check digit. Return '' otherwise. =back =head2 EXPORT None by default. =head1 AUTHOR Mathias Weidner, C<< >> =head1 THANKS Jonathan Peters wrote L from which I took the routine to compute the checkdigits. =head1 SEE ALSO L, L, L, L =cut Algorithm-CheckDigits-v1.3.6/t000755001750001750 014144705550 16523 5ustar00mathiasmathias000000000000Algorithm-CheckDigits-v1.3.6/t/94-version.t000444001750001750 61514144705550 20746 0ustar00mathiasmathias000000000000# taken from http://perlmaven.com/consistent-version-numbers-of-modules use strict; use warnings; use Test::More; ## no critic eval q{use Test::Version 1.003001 qw( version_all_ok ), { is_strict => 1, has_version => 1, consistent => 1, }; }; plan skip_all => "Test::Version 1.003001 required for testing version numbers" if $@; version_all_ok(); done_testing; Algorithm-CheckDigits-v1.3.6/t/PluginLibA.pm000444001750001750 334314144705550 21207 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 si et: package PluginLibA; use strict; use warnings; use Algorithm::CheckDigits; # This module inherits from Algorithm::CheckDigits end reexports the function # CheckDigits() so the user of this module does not need to explicitely # 'use Algorithm::CheckDigits;'. our @EXPORT = qw(CheckDigits); our @ISA = qw(Algorithm::CheckDigits); # These variables store the keys under which the variants of the algorithm in # this module are registered with Algorithm::CheckDigits. They must be made # publicly accessible for the user of this module. our $meth1 = Algorithm::CheckDigits::plug_in('PluginLibA', 'returns 1', 'pla'); our $meth2 = Algorithm::CheckDigits::plug_in('PluginLibA', 'returns 2', 'pla'); # It's possible to use the -> notation to access the plug_in() function. our $meth3 = Algorithm::CheckDigits->plug_in('PluginLibA', 'returns 3', 'pla'); # Since this module provides variants of the algorithm it stores the key used # to create the instance, which is given as the first argument after the class # name. sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); return $self; } # new() # This is just one example on how to use the registration keys returned by # Algorithm::CheckDigits::plug_in(). my %methods = ( $meth1 => 1, $meth2 => 2, $meth3 => 3, ); sub is_valid { my ($self,$number) = @_; return $methods{$self->{type}} == $number; } sub complete { my ($self) = @_; return $methods{$self->{type}}; } sub basenumber { my ($self) = @_; return $methods{$self->{type}}; } sub checkdigit { my ($self) = @_; return $methods{$self->{type}}; } 1; Algorithm-CheckDigits-v1.3.6/t/PluginLibB.pm000444001750001750 447714144705550 21221 0ustar00mathiasmathias000000000000# vim: set ts=4 sw=4 tw=78 si et: package PluginLibB; # This module is usable either as a plugin for Algorithm::CheckDigits or # stand-alone. As a plugin one can create instances with the CheckDigits() # function from Algorithm::CheckDigits. If that modulue is not available, # it is possible to create instances with PluginLibB->new(). # See pluginlibb.t and pluginlibb-without.t for example usage. use strict; use warnings; # These variables store the keys under which the variants of the algorithm in # this module will be registered with Algorithm::CheckDigits if that module is # available. They must be made publicly accessible for the user of this module. # # If there are no variations of the algorithm, it is not necessary to use such # variables in stand-alone mode. But for usage together with # Algorithm::CheckDigits at least one method per variant is mandatory. our ($meth1,$meth2,$meth3); # Since this module should work regardless of the availability of # Algorithm::CheckDigits we have to 'eval "use Algorithm::CheckDigits";'. eval "use Algorithm::CheckDigits"; if ($@) { $meth1 = 'plb1'; $meth2 = 'plb2'; $meth3 = 'plb3'; } else { $meth1 = Algorithm::CheckDigits::plug_in('PluginLibB', 'returns 1', 'plb1'); $meth2 = Algorithm::CheckDigits::plug_in('PluginLibB', 'returns 2', 'plb2'); # It's possible to use the -> notation to access the plug_in() function. $meth3 = Algorithm::CheckDigits->plug_in('PluginLibB', 'returns 3', 'plb3'); } # Since this module provides variants of the algorithm it stores the key used # to create the instance, which is given as the first argument after the class # name. sub new { my $proto = shift; my $type = shift; my $class = ref($proto) || $proto; my $self = bless( {}, $class ); $self->{type} = lc($type); return $self; } # new() # This is just one example on how to use the registration keys returned by # Algorithm::CheckDigits::plug_in(). my %methods = ( $meth1 => 1, $meth2 => 2, $meth3 => 3, ); sub is_valid { my ($self,$number) = @_; return $methods{$self->{type}} == $number; } sub complete { my ($self) = @_; return $methods{$self->{type}}; } sub basenumber { my ($self) = @_; return $methods{$self->{type}}; } sub checkdigit { my ($self) = @_; return $methods{$self->{type}}; } 1; Algorithm-CheckDigits-v1.3.6/t/checkdigits.t000444001750001750 72214144705550 21307 0ustar00mathiasmathias000000000000# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test; BEGIN { plan tests => 1 }; use Algorithm::CheckDigits; ok(1); ######################### # Insert your test code below, the Test module is use()ed here so read # its man page ( perldoc Test ) for help writing this test script. Algorithm-CheckDigits-v1.3.6/t/ecno.t000444001750001750 110714144705550 17770 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 13); }; use Algorithm::CheckDigits; my $ecno = CheckDigits('ECNo'); # ok(not $ecno->is_valid("200-001-0")); ok(not $ecno->is_valid("200-001-1")); ok(not $ecno->is_valid("200-001-2")); ok(not $ecno->is_valid("200-001-3")); ok(not $ecno->is_valid("200-001-4")); ok(not $ecno->is_valid("200-001-5")); ok(not $ecno->is_valid("200-001-6")); ok(not $ecno->is_valid("200-001-7")); ok($ecno->is_valid("200-001-8")); ok(not $ecno->is_valid("200-001-9")); ok($ecno->is_valid("220-001-1")); ok($ecno->is_valid("230-001-3")); ok($ecno->is_valid("310-001-0")); Algorithm-CheckDigits-v1.3.6/t/esr5_ch.t000444001750001750 36414144705550 20360 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 2); }; use Algorithm::CheckDigits; my $esr5 = CheckDigits('esr5_ch'); # my $number = '0001000012000 241170032660178 10304'; ok($esr5->is_valid('05' . $number)); ok('05' . $number eq $esr5->complete($number)); Algorithm-CheckDigits-v1.3.6/t/iban.t000444001750001750 457414144705550 17770 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 44); }; use Algorithm::CheckDigits; my $iban = CheckDigits('iban'); # ok($iban->is_valid("AD12 0001 2030 2003 5910 0100")); ok($iban->is_valid("BE68 5390 0754 7034")); ok($iban->is_valid("BA39 1290 0794 0102 8494")); ok($iban->is_valid("BG80 BNBG 9661 1020 3456 78")); ok($iban->is_valid("DK50 0040 0440 1162 43")); ok($iban->is_valid("DE89 3704 0044 0532 0130 00")); ok($iban->is_valid("EE38 2200 2210 2014 5685")); ok($iban->is_valid("FI21 1234 5600 0007 85")); ok($iban->is_valid("FO97 5432 0388 8999 44")); ok($iban->is_valid("FR14 2004 1010 0505 0001 3M02 606")); ok($iban->is_valid("GI75 NWBK 0000 0000 7099 453")); ok($iban->is_valid("GR16 0110 1250 0000 0001 2300 695")); ok($iban->is_valid("GL56 0444 9876 5432 10 ")); ok($iban->is_valid("GB29 NWBK 6016 1331 9268 19")); ok($iban->is_valid("IE29 AIBK 9311 5212 3456 78")); ok($iban->is_valid("IS14 0159 2600 7654 5510 7303 39")); ok($iban->is_valid("IT60 X054 2811 1010 0000 0123 456")); ok($iban->is_valid("HR12 1001 0051 8630 0016 0")); ok($iban->is_valid("LV80 BANK 0000 4351 9500 1")); ok($iban->is_valid("LT12 1000 0111 0100 1000")); ok($iban->is_valid("LI21 0881 0000 2324 013A A")); ok($iban->is_valid("LU28 0019 4006 4475 0000")); ok($iban->is_valid("MK07 3000 0000 0042 425")); ok($iban->is_valid("MT84 MALT 0110 0001 2345 MTLC AST0 01S")); ok($iban->is_valid("MU56 BOMM 0101 1234 5678 9101 0000 00")); ok($iban->is_valid("MC93 2005 2222 1001 1223 3M44 555")); ok($iban->is_valid("NL91 ABNA 0417 1643 00")); ok($iban->is_valid("NO93 8601 1117 947")); ok($iban->is_valid("AT61 1904 3002 3457 3201")); ok($iban->is_valid("PL27 1140 2004 0000 3002 0135 5387")); ok($iban->is_valid("PT50 0002 0123 1234 5678 9015 4")); ok($iban->is_valid("RO49 AAAA 1B31 0075 9384 0000")); ok($iban->is_valid("SM62 Y054 3219 8760 0444 5333 222")); ok($iban->is_valid("CS73 2600 0560 1001 6113 79")); ok($iban->is_valid("SE35 5000 0000 0549 1000 0003")); ok($iban->is_valid("CH93 0076 2011 6238 5295 7")); ok($iban->is_valid("SK31 1200 0000 1987 4263 7541")); ok($iban->is_valid("SI56 1910 0000 0123 438")); ok($iban->is_valid("ES91 2100 0418 4502 0005 1332")); ok($iban->is_valid("CZ65 0800 0000 1920 0014 5399")); ok($iban->is_valid("TN59 1420 7207 1007 0712 9648")); ok($iban->is_valid("TR33 0006 1005 1978 6457 8413 26 ")); ok($iban->is_valid("HU42 1177 3016 1111 1018 0000 0000")); ok($iban->is_valid("CY17 0020 0128 0000 0012 0052 7600")); Algorithm-CheckDigits-v1.3.6/t/imei.t000444001750001750 66614144705550 17760 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 5); }; use Algorithm::CheckDigits; my $imei = CheckDigits('IMEI'); # ok($imei->is_valid("260531793113837")); ok(not $imei->is_valid("260531793113838")); # you have to use method 'imeisv' if your number contains the software version ok(not $imei->is_valid("26053179311383347")); my $imeisv = CheckDigits('IMEISV'); ok($imeisv->is_valid("26053179311383127")); ok($imeisv->is_valid("26053179311383347")); Algorithm-CheckDigits-v1.3.6/t/isbn13.t000444001750001750 77214144705550 20132 0ustar00mathiasmathias000000000000use Test; BEGIN { plan ( tests => 4, # todo => [3], ); }; use Algorithm::CheckDigits; my $isbn13 = CheckDigits('isbn13'); my $ean = CheckDigits('ean'); my $isbn_number = "9783492233163"; my $ean_but_not_isbn_number = "7622200004607"; ok($isbn13->is_valid($isbn_number),1, "valid ISBN"); ok($ean->is_valid( $isbn_number),1, "valid EAN"); ok($isbn13->is_valid($ean_but_not_isbn_number),'', "valid EAN but not ISBN"); ok($ean->is_valid( $ean_but_not_isbn_number),1, "valid EAN"); Algorithm-CheckDigits-v1.3.6/t/nip.t000444001750001750 106114144705550 17631 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 11); }; use Algorithm::CheckDigits; my $nip = CheckDigits('nip'); # my $number = '768000246'; ok(not $nip->is_valid($number . '0')); ok(not $nip->is_valid($number . '1')); ok(not $nip->is_valid($number . '2')); ok(not $nip->is_valid($number . '3')); ok(not $nip->is_valid($number . '4')); ok(not $nip->is_valid($number . '5')); ok($nip->is_valid($number . '6')); ok(not $nip->is_valid($number . '7')); ok(not $nip->is_valid($number . '8')); ok(not $nip->is_valid($number . '9')); ok($number . '6' eq $nip->complete($number)); Algorithm-CheckDigits-v1.3.6/t/plugina.t000444001750001750 131114144705550 20500 0ustar00mathiasmathias000000000000use Test::More; use lib qw( t ); # Since the module PluginLibA reexports the function CheckDigits() from # Algorithm::CheckDigits, we do not need to explicitly use that module to get # the function into our name space. use PluginLibA; # To get access to the algorithm provided by module PluginLibA, we have to use # the keys stored in these publicly accessible variables. my $cd1 = CheckDigits($PluginLibA::meth1); my $cd2 = CheckDigits($PluginLibA::meth2); my $cd3 = CheckDigits($PluginLibA::meth3); is($cd1->checkdigit(234), 1, 'checked method1 of PluginLibA'); is($cd2->basenumber(234), 2, 'checked method2 of PluginLibA'); is($cd3->complete(234), 3, 'checked method3 of PluginLibA'); done_testing(); Algorithm-CheckDigits-v1.3.6/t/pluginb-without.t000444001750001750 103214144705550 22202 0ustar00mathiasmathias000000000000use Test::More; use lib qw( t ); use PluginLibB; # To get access to the algorithm provided by module PluginLibB, we have to use # the keys stored in these publicly accessible variables. my $cd1 = PluginLibB->new($PluginLibB::meth1); my $cd2 = PluginLibB->new($PluginLibB::meth2); my $cd3 = PluginLibB->new($PluginLibB::meth3); is($cd1->checkdigit(234), 1, 'checked method1 of PluginLibB'); is($cd2->basenumber(234), 2, 'checked method2 of PluginLibB'); is($cd3->complete(234), 3, 'checked method3 of PluginLibB'); done_testing(); Algorithm-CheckDigits-v1.3.6/t/pluginb.t000444001750001750 134314144705550 20506 0ustar00mathiasmathias000000000000use Test::More; use lib qw( t ); # Since PluginLibB does not inherit from Algorithm::CheckDigits we have to use # Algorithm::CheckDigits here to make use of the function CheckDigits() to get # our algorithm checker. # use Algorithm::CheckDigits; use PluginLibB; # To get access to the algorithm provided by module PluginLibB, we have to use # the keys stored in these publicly accessible variables. my $cd1 = CheckDigits($PluginLibB::meth1); my $cd2 = CheckDigits($PluginLibB::meth2); my $cd3 = CheckDigits($PluginLibB::meth3); is($cd1->checkdigit(234), 1, 'checked method1 of PluginLibB'); is($cd2->basenumber(234), 2, 'checked method2 of PluginLibB'); is($cd3->complete(234), 3, 'checked method3 of PluginLibB'); done_testing(); Algorithm-CheckDigits-v1.3.6/t/pod-coverage.t000444001750001750 32614144705550 21401 0ustar00mathiasmathias000000000000use Test::More; eval "use Test::Pod::Coverage 1.00"; plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD coverage" if $@; my $trustme = { trustme => [qr/^new$/] }; all_pod_coverage_ok( $trustme ); Algorithm-CheckDigits-v1.3.6/t/pod.t000444001750001750 20114144705550 17600 0ustar00mathiasmathias000000000000use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); Algorithm-CheckDigits-v1.3.6/t/script-checkdigits.t000444001750001750 221014144705550 22623 0ustar00mathiasmathias000000000000use strict; use File::Spec; use Probe::Perl; use Test::More; plan tests => 5; my $perl = Probe::Perl->find_perl_interpreter; my $script = File::Spec->catfile(qw/bin checkdigits.pl/); # first check whether script with option -help or -man runs # is(system($perl, $script, '-help'),0, "run with -help"); is(system($perl, $script, '-man'),0, "run with -man"); my ($pipe,$out,@args); @args = qw(-algorithm isbn check 1-55860-701-3); # # On MSWin32: List form of pipe open not implemented # open($pipe, join(' ', $perl, $script, @args, '|')); $out = <$pipe>; close $pipe; like($out,qr/^valid$/,"checked with ISBN algorithm"); @args = qw(-algorithm isbn checkdigit 1-55860-701-3); # # On MSWin32: List form of pipe open not implemented # open($pipe, join(' ', $perl, $script, @args, '|')); $out = <$pipe>; close $pipe; like($out,qr/^3$/,"checked and separated checkdigit with ISBN algorithm"); @args = qw(-algorithm isbn complete 1-55860-701-); # # On MSWin32: List form of pipe open not implemented # open($pipe, join(' ', $perl, $script, @args, '|')); $out = <$pipe>; close $pipe; like($out,qr/^1-55860-701-3$/,"completed checkdigit with ISBN algorithm"); Algorithm-CheckDigits-v1.3.6/t/sedol.t000444001750001750 200214144705550 20145 0ustar00mathiasmathias000000000000use Test::More tests => 67; BEGIN { use_ok 'Algorithm::CheckDigits' }; my $sedol = CheckDigits( 'sedol' ); isa_ok( $sedol, 'Algorithm::CheckDigits' ); my %sedols = ( 228276 => 5, 232977 => 0, 406566 => 3, 557910 => 7, 585284 => 2, 710889 => 9, B00030 => 0, B01841 => 1, B0YBKJ => 7, B0YBKL => 9, B0YBKR => 5, B0YBKT => 7, B0YBLH => 2, ); for my $base ( sort keys %sedols ) { my $check = $sedols{$base}; my $full = $base . $check; is $sedol->complete( $base ), $full, "$base -> $full"; ok $sedol->is_valid( $full ), "$full is valid"; is $sedol->basenumber( $full ), $base, "$full base is $base"; is $sedol->checkdigit( $full ), $check, "$full check is $check"; my $bad = $base . ($check eq '0' ? '1' : '0'); ok !$sedol->is_valid( $bad ), "$bad has wrong check digit"; } Algorithm-CheckDigits-v1.3.6/t/tin_ie.t000444001750001750 153314144705550 20316 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 12); }; use Algorithm::CheckDigits; my $tin_ie = CheckDigits('tin_ie'); # # [ 'ustid_ie', '8473625E', '8473625', 'E', # '8473625A' ], # [ 'tin_ie', '1234567T', '1234567', 'T', # '8473625A' ], # [ 'tin_ie', '1234567TW', '1234567?W', 'T', # '8473625AW' ], # [ 'tin_ie', '1234577W', '1234577', 'W', # '8473625A' ], ok($tin_ie->is_valid("8473625E")); ok(not $tin_ie->is_valid("8473625A")); ok($tin_ie->is_valid("1234567T")); ok(not $tin_ie->is_valid("1234567A")); ok($tin_ie->is_valid("1234567TW")); ok(not $tin_ie->is_valid("1234567AW")); ok($tin_ie->is_valid("1234577W")); ok(not $tin_ie->is_valid("1234577A")); ok($tin_ie->is_valid("1234577WW")); ok(not $tin_ie->is_valid("1234577AW")); ok($tin_ie->is_valid("1234577IA")); ok(not $tin_ie->is_valid("1234577AA")); Algorithm-CheckDigits-v1.3.6/t/upc.t000444001750001750 41714144705550 17616 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 1); }; use Algorithm::CheckDigits; my $upc = CheckDigits('upc'); # there was an error exposed with that number, so I include it here to # avoid making that error again. # # Thanks to Aaron W. West # ok($upc->is_valid("724358016420")); Algorithm-CheckDigits-v1.3.6/t/ustid_be.t000444001750001750 50514144705550 20623 0ustar00mathiasmathias000000000000use Test; BEGIN { plan(tests => 4); }; use Algorithm::CheckDigits; my $ustid_be = CheckDigits('ustid_be'); # ok($ustid_be->is_valid('BE0473700488')); ok($ustid_be->complete('BE04737004'),'BE0473700488'); ok($ustid_be->basenumber('BE0473700488'),'04737004'); ok($ustid_be->checkdigit('BE0473700488'),'88'); # end of tests Algorithm-CheckDigits-v1.3.6/t/valid.data000444001750001750 2002714144705550 20633 0ustar00mathiasmathias000000000000use vars qw(@testcases); @testcases = ( # M007 [ 'ismn', 'M-345-24680-5', 'M-345-24680', '5', 'M-345-24689-0' ], # M011 [ 'upc', '012345678905', '01234567890', '5', '012345678901' ], # M012 [ 'sedol', '0123457', '012345', '7', '0123456' ], [ 'sedol', 'B0YBLH2', 'B0YBLH', '2', 'B0YBLH3' ], # M013 [ 'postcheckkonti', '85-12345678-7', '85-12345678-', '7', '85-12345678-9' ], # M014 [ 'isbn', '3-88229-192-3', '3-88229-192-', '3', '3-88229-192-0' ], [ 'issn', '0724-8679', '0724-867', '9', '0724-8870' ], [ 'ustid_pt', '136695973', '13669597', '3', '136695970' ], [ 'vatrn_pt', '136695973', '13669597', '3', '136695970' ], [ 'hkid', 'K1234560', 'K123456', '0', 'K1234567' ], [ 'wagonnr_br', '123456-1', '123456-', '1', '123456-7' ], [ 'nhs_gb', '3882291850', '388229185', '0', '3882291851' ], [ 'vat_sl', '59082437', '5908243', '7', '59082432' ], # M015 [ 'pzn', '4877800', '487780', '0', '4877801' ], # MBase-002 [ 'blutbeutel', '2761011234567893', '276101123456789', '3', '2761011234567890' ], [ 'blutbeutel', '02', '0', '2', '01' ], [ 'blutbeutel', '19', '1', '9', '10' ], [ 'blutbeutel', '60', '6', '0', '61' ], [ 'blutbeutel', '94', '9', '4', '90' ], [ 'blutbeutel', '08235', '0823', '5', '08234' ], [ 'blutbeutel', '2766169732125615', '276616973212561', '5', '2766169732125610' ], [ 'bzue_de', '9433463951409', '943346395140', '9', '9433463951400' ], [ 'ustid_de', '136 695 976', '136 695 97', '6', '136 695 970' ], # MBase-003 [ 'sici', '0724-8679(20040308)6:<138>2.0.TX;2-H', '0724-8679(20040308)6:<138>2.0.TX;2-', 'H', '0724-8679(20040308)6:<138>2.0.TX;2-A', ], # I don't know what for this method is. # M07-001 #[ 'm07-001', '0', '', '0', # '1' ], #[ 'm07-001', '1234567892', '123456789', '2', # '1234567890' ], # M09-001 [ 'euronote', 'X03854465012', 'X0385446501', '2', 'X03854465010' ], [ 'euronote', 'P02044163566', 'P0204416356', '6', 'P02044163560' ], # M10-001 [ 'amex', '3400 000000 00009', '3400 000000 0000', '9', '3400 000000 00000' ], [ 'diners', '3000 0000 0000 04', '3000 0000 0000 0', '4', '3000 0000 0000 00' ], [ 'diners', '3600 0000 0000 08', '3600 0000 0000 0', '8', '3600 0000 0000 00' ], [ 'discover', '6011 0000 0000 0004', '6011 0000 0000 000', '4', '6011 0000 0000 0000' ], [ 'enroute', '2014 0000 0000 009', '2014 0000 0000 00', '9', '2014 0000 0000 000' ], [ 'jcb', '3088 0000 0000 0009', '3088 0000 0000 000', '9', '3038 0000 0000 0001' ], [ 'mastercard', '5500 0000 0000 0004', '5500 0000 0000 000', '4', '5500 0000 0000 0000' ], [ 'visa', '4111 1111 1111 1111', '4111 1111 1111 111', '1', '4111 1111 1111 1110' ], [ 'isin', 'DE0005557508', 'DE000555750', '8', 'DE0005557509' ], [ 'cusip', '023135106', '02313510', '6', '023135107' ], [ 'cusip', '037833100', '03783310', '0', '03783310B' ], [ 'cusip', 'G8572F100', 'G8572F10', '0', 'G8572F101' ], [ 'cusip', '392690QT3', '392690QT', '3', '0378#3100' ], [ 'cusip', 'Y8295N109', 'Y8295N10', '9', 'Y8295N103' ], # M10-002 # the test number from www.pruefziffernberechnung.de seems to be # invalid # [ 'siret', '12345678200787', '1234567820078', '7' ], [ 'siren', '732 829 320', '732 829 32', '0', '732 829 321' ], [ 'siret', '73282932000074', '7328293200007', '4', '73282932000070' ], # M10-004 [ 'ean', '7622200004607', '762220000460', '7', '7622200004600' ], [ 'isbn13', '9783492233163', '978349223316', '3', '9783492233160' ], [ '2aus5', '1234565', '123456', '5', '1234567' ], [ 'isbn13', '9783882291858', '978388229185', '8', '9783882291851' ], # M10-005 [ 'identcode_dp', '21.802 580.906 6', '21.802 580.906 ', '6', '21.802 580.906 0' ], # M10-006 [ 'rentenversicherung', '65180539W001', '65180539W00', '1', '65180539W000' ], # M10-009 [ 'betriebsnummer', '09912342', '0991234', '2', '09912340' ], # M10_011 [ 'ups', '1Z 591580 68 55587736', '1Z 591580 68 5558773', '6', '1Z 591580 68 55587730' ], # M11-003 [ 'pkz', '150765400354', '15076540035', '4', '150765400350' ], [ 'pkz', '110488414857', '11048841485', '7', '110488414850' ], # M11-004 [ 'cpf', '043.033.407-90', '043.033.407-', '90', '043.033.407-91' ], [ 'titulo_eleitor', '181497628-60', '181497628-', '60', '181497628-61' ], # M11-006 [ 'ccc_es', '2420-0730-27-0050103552', '2420-0730- -0050103552', '27', '2420-0730-20-0050103552' ], # M11-007 [ 'ustid_fi', '13669598', '1366959', '8', '13669590' ], # M11-008 [ 'ustid_dk', '13585628', '13585628', '', '13585620' ], # M11-009 [ 'nric_sg', 'S1234567D', 'S1234567', 'D', 'S1234567A' ], [ 'nric_sg', '1234567D', '1234567', 'D', '1234567A' ], # M11-016 [ 'ustid_pl', '8567349219', '856734921', '9', '8567349210' ], # M11-010 [ 'ahv_ch', '123.45.678.113', '123.45.678.11', '3', '123.45.678.110' ], # M11-011 [ 'ustid_nl', '123456782', '12345678', '2', '123456783' ], [ 'ustid_nl', '007677595B04', '00767759.B04', '5', '007677593B04' ], # M11-012 [ 'bwpk_de', '151058-D-20711', '151058-D-2071', '1', '151058-D-20712' ], # M11-013 [ 'ustid_gr', '123456783', '12345678','3', '123456789' ], # M11-015 [ 'esr5_ch', '050001000012000 241170032660178 10304', '0001000012000 241170032660178 10304', '05', '060001000012000 241170032660178 10304' ], # M11-017 [ 'ecno', '200-235-0', '200-235-', '0', '200-235-1' ], # M16-001 [ 'isan', '123A567B8912E01A', '123A567B8912E01', 'A', '123A567B8912E01B' ], # M23-001 [ 'dni_es', '54362315-K', '54362315-', 'K', '54362315-A' ], # M23-002 [ 'ustid_ie', '8473625E', '8473625', 'E', '8473625A' ], [ 'tin_ie', '1234567T', '1234567', 'T', '1234567A' ], [ 'tin_ie', '1234567TW', '1234567.W', 'T', '1234567AW' ], [ 'tin_ie', '1234577W', '1234577', 'W', '1234577A' ], [ 'tin_ie', '1234577WW', '1234577.W', 'W', '1234577AW' ], [ 'tin_ie', '1234577IA', '1234577.A', 'I', '1234577AA' ], # M43-001 [ 'code_39', 'AB-123K', 'AB-123', 'K', 'AB-123A' ], # M89-001 [ 'ustid_lu', '13669580', '136695', '80', '13669581' ], # M97-001 [ 'ustid_be', '136695962', '1366959', '62', '136695960' ], [ 'ustid_be', '0473700488', '04737004', '88', '0473700489' ], # M97-002 [ 'iban', 'DE88 2008 0000 09703 7570 0', 'DE00 2008 0000 09703 7570 0', '88', 'DE12 2008 0000 09703 7570 0' ], # MXX-001 [ 'pa_de', '2406055684D<6810203<0705109<6', '240605568_D<681020_<070510_<_', '4<3<9<6', '2406055684D<6810203<0705109<4' ], [ 'pa_de', '2406055684', '240605568', '4', '2406055683' ], [ 'pa_de', '6810203', '681020', '3', '6810204' ], [ 'pa_de', '0705109', '070510', '9', '0705106' ], [ 'aba_rn', '789456124', '78945612', '4', '789456125' ], # MXX-002 [ 'cas', '1333-74-0', '1333-74-', '0', '1333-74-1' ], [ 'cas', '107-07-3', '107-07-', '3', '107-07-1' ], [ 'cas', '1021205-92-4', '1021205-92-', '4', '1021205-92-1' ], # MXX-003 [ 'dem', 'GD0645027K1', 'GD0645027K', '1', 'GD0645027K0' ], # MXX-004 [ 'ustid_at', 'U13585627', 'U1358562', '7', 'U13585620' ], # MXX-005 [ 'esr9_ch', '123456786', '12345678', '6', '123456789' ], # MXX-006 [ 'verhoeff', '14567894', '1456789', '4', '14657894' ], ); Algorithm-CheckDigits-v1.3.6/t/valid.t000444001750001750 176214144705550 20152 0ustar00mathiasmathias000000000000# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' use vars qw(@testcases); use Test; BEGIN { do 't/valid.data'; plan(tests => ($#testcases + 1) * 5); }; use Algorithm::CheckDigits; my $checkdigit; foreach my $tcase (@testcases) { if ($checkdigit = CheckDigits($tcase->[0])) { my $is_valid = $checkdigit->is_valid($tcase->[1]); ok($is_valid ,1 ,"is_valid $tcase->[0] $tcase->[1]" ); my $skip = not $is_valid; skip($skip ,$checkdigit->complete($tcase->[2]) ,$tcase->[1] ,"complete $tcase->[0]" ); skip($skip ,$checkdigit->basenumber($tcase->[1]) ,$tcase->[2] ,"basenumber $tcase->[0]" ); skip($skip ,$checkdigit->checkdigit($tcase->[1]) ,$tcase->[3] ,"checkdigit $tcase->[0]" ); skip($skip ,(not $checkdigit->is_valid($tcase->[4])) ,1 ,"not is_valid $tcase->[0]: $tcase->[4]" ); } }