in reply to Digest (checksum) Algorithm for 12 Decimal Digits?

You can fit up to 39 bits into 12 decimal digits.

Get the 39 lower bits for the MD5 of your data, convert them to a number and then to a string:

use Digest::MD5 qw(md5); my $md5 = md5($data); my $end = substr($md5, -5) & "\x7f\xff\xff\xff\xff"; my $acu = 0; $acu = $acu * 256 + ord $_ for split(//, $end); printf "%012.0f\n", $acu;

Replies are listed 'Best First'.
Re^2: Digest (checksum) Algorithm for 12 Decimal Digits? (32bit)
by oha (Friar) on Oct 08, 2007 at 12:22 UTC
    ++ a good and easy example, and a good use of & in string context,

    we must note that we have a bit more then half the possible results we could get with a 12 digit solution. (first digit will be 0..5)
    also, we must note that we require 64 bit algebra.

    iff we have 64 bit algebra, we could return a modulo, there is some more population on lower buckets but it's less then 0.1%, on the other hand we would have about the double of bucket, giving the OP less risks of clashing.

    without 64 bit algebra, things get a little more complex:

    my $md5 = ...; my $lo = 0; my $hi = 0; for(split //, $md5) { $lo = $lo*256 + ord; $hi = $hi*256 + $lo / 1_000_000; $lo = $lo % 1_000_000; $hi = $hi % 1_000_000; } return $hi.$lo;
      64 bit algebra is not really required.

      The double floats used by perl internally can represent 53 bit integers on most CPU architectures, enough to store the 12 decimal digits:

      my $md5 = ...; my $dd = 0; $dd = ($dd * 256 + ord) % 1e12 for split //, $md5; print "$dd\n";
      (actually, the biggest number that can appear in this algorithm is 2.56E+14, that can be represented in 48 bits)