Частично ваша проблема может заключаться в том, что вы используете математику с плавающей запятой, а BKDR почти наверняка требует целочисленную математику. Вы можете исправить эту ошибку, сказав
my @chars = split(//,$hash_var);
my $hash = 0;
my $seed = 31;
for my $char ( @chars ) {
use integer;
if( $char !~ m/\d/ ) {
$hash = ( $seed * $hash ) + ord( $char );
}
else {
$hash = ( $seed * $hash ) + $char ;
}
}
$hash = ( $hash & 0x7FFFFFFF ) % 1000;
$hash = "$chars[0]$chars[$#chars]$hash" ;
Еще один трюк, который может помочь, - это использование символов, отличных от первого и последнего. Если первый и последний символы имеют тенденцию быть одинаковыми, они не добавляют уникальности хешу.
Возможно, вы также захотите использовать лучшую хеш-функцию, такую как MD5 (доступна в Digest :: MD5), и обрезать результат до желаемого размера. Однако тот факт, что вы вообще используете хеш, означает, что вы рискуете столкнуться.