#!/usr/bin/perl -w
#
# $Revision: 1.5 $ $Date: 2012-07-26 17:11:48-04 $
# $Source: /home/vogelke/bin/RCS/sdelf,v $
# $Host: sys7.com $
# $UUID: 075506e1-b229-346e-b66e-e8d86101f719 $
#
#<sdelf: print merged Elf/SDBM hash for each line (64-bit only).

use strict;
my $hash;

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

# ----------------------------------------------------------------
# Accept string, return SDBM + Elf hash.

sub sdelf {
    my ($str) = @_;
    my ($byte, $j, $k, $hash);
    use integer;

    $hash = 0;
    $j    = 0;
    $k    = 0;

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

    foreach $byte (unpack("C*", $str)) {
        # Elf hash.
        $k++;
        $hash = ($hash << 8) + $byte + $k;

        if ($j = $hash & 0xF0000000) {
            $hash ^= $j >> 48;
        }
        $hash &= ~$j;

        # SDBM hash.
        $hash += $k;
        $hash = $byte + 9999991 * $hash;
    }

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