Acrux
view release on metacpan or search on metacpan
lib/Acrux/Digest/M11R.pm view on Meta::CPAN
=head1 SYNOPSIS
use Acrux::Digest::M11R;
my $m11r = Acrux::Digest::M11R->new();
my $digest = $m11r->digest( "123456789" ); # 5
=head1 DESCRIPTION
This is Digest backend module that provides calculate the modulus 11 (recursive) check digit
=head1 METHODS
This class inherits all methods from L<Acrux::Digest> and implements the following new ones
=head2 digest
my $digest = $m11r->digest( "123456789" ); # 5
Returns M11R checkdigit by specified digits-string
=head1 HISTORY
See C<Changes> file
=head1 TO DO
See C<TODO> file
=head1 SEE ALSO
L<Acrux::Digest>, L<Algorithm::CheckDigits::M11_015>, B<check_okpo()>
=head1 AUTHOR
Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>
=head1 COPYRIGHT
Copyright (C) 1998-2026 D&D Corporation
=head1 LICENSE
This program is distributed under the terms of the Artistic License Version 2.0
See the C<LICENSE> file or L<https://opensource.org/license/artistic-2-0> for details
=cut
use Carp;
use parent qw/Acrux::Digest/;
sub digest {
# See also: Algorithm::CheckDigits::M11_015 and check_okpo()
my $self = shift;
my $data = shift;
$self->data($data) if defined $data;
my $test = $self->data;
croak "Incorrect input digit-string" if !defined($test) || $test =~ m/[^0-9]/g;
my $len = length($test);
my $iters = ($len + (($len & 1) ? 1 : 0)) / 2;
my @digits = split(//, $test); # Get all digits from input string of chars
#printf "Test=%s; len=%d; iters=%d\n", $test, $len, $iters;
my $w_lim = 10; # Maximum for round-robin(10) weight list: 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5...
my $step = 2; # Step for weight list offset calculation for next iteration
# Calculation sum for one weight list by ofset
my $calc = sub {
my $off = shift || 0;
my $s = 0;
for (my $i = 0; $i < $len; $i++) {
my $w = (($i + $off) % $w_lim) + 1;
$s += ($w * $digits[$i]);
#printf " > i=%d; d=%d; w=%d; sum=%d\n", $i, $digits[$i], $w, $s;
}
return $s % 11;
};
# Main cycle
my $sum = 0;
for (my $j = 0; $j < $iters; $j++) {
my $offset = $j*$step;
$sum = $calc->($offset);
#printf " >> j=%d; offset=%d; sum=%d\n", $j, $offset, $sum;
last if $sum < 10;
}
$sum = 0 if $sum >= 10; # 0 if incorrect again
#printf " >>> sum=%d\n", $sum;
return $sum;
}
1;
__END__
( run in 0.704 second using v1.01-cache-2.11-cpan-5a3173703d6 )