#!/usr/bin/perl -w
#
# $Revision: 1.4 $ $Date: 2012-07-26 17:11:48-04 $
# $Source: /home/vogelke/bin/RCS/sdbm,v $
# $Host: sys7.com $
# $UUID: 9331670b-d97a-32c6-941e-b81ec5a14294 $
#
#<sdbm: print SDBM hash for each line.
# Works for either 32-bit or 64-bit perl.

use strict;
use Config;

my $hash;
my $prime = defined $Config{use64bitint} ? 9999991 : 65587;

while (<>) {
    chomp;
    $hash = sdbm($prime, $_);
    print "$hash $_\n";
}
exit(0);

# ----------------------------------------------------------------
# Accept string, return slightly-modified SDBM hash.
# Primes: 65587 for 32-bit, 9999991 for 64-bit.

sub sdbm {
    my ($prime, $str) = @_;
    use integer;

    my $sum = 0;
    my $k = 0;

    # Add a counter ($k) to make sure that different-sized blocks
    # of the same character don't give the same sum.

    foreach my $byte (unpack("C*", $str)) {
        $k++;
        $sum = $k + $byte + $prime * $sum;
    }

    no integer;
    return sprintf("%16.16x", $sum);
}
