Re: [Exim] Using nhash with the UoW imapd/qpopper

トップ ページ
このメッセージを削除
このメッセージに返信
著者: Yann Golanski
日付:  
To: Nick O'Brien
CC: exim-users
題目: Re: [Exim] Using nhash with the UoW imapd/qpopper
On Wed, Jun 07, 2000 at 02:55:11PM +0100, Nick O'Brien wrote:
> We are looking to split our mail spool using nhash, in Exim 3.14. We are
> also using the UoW imapd (v4.7c) and qpopper, and I am trying to
> incorporate nhash into those as well.
>
> Admittedly my C is a bit rusty, but I have been having problems
> disentangling the code for nhash from the rest of source, so I can then
> slot it into the imapd and qpopper sources. I've extracted the main
> potions of the code from expand.c and am trying to hack into a form I can
> use.


What don't you understand in it?

It works on the following basis: Take a string, convert each letter to a
number and weight that number by a prime number, making sure the largest
prime used is the first. This computes a large number. Do a div/mod
operation on it and get two ints between the two values you gave it.

The only possible bug is if you have users named like:
    zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz@???
Then you might get a NaN error as no boundary are checked. However, this
is very unlikly. With 2.5 millions users, I never had a problem with
this.


Yes, I know I was slacking off when I wrote it ;>

> What is the best way to try and attempt this or has anyone produced any
> patches for the UoW imapd and qpopper?


Donno if it helps, but here is a perl function for it:

my @prime = (
  "2",  "3",    "5",   "7",  "11",  "13",  "17",  "19",  "23",  "29",
 "31", "37",   "41",  "43",  "47",  "53",  "59",  "61",  "67",  "71",
 "73", "79",   "83",  "89",  "97", "101", "103", "107", "109", "113"
);
my $nbr_primes = 30;


# nhash sub
sub nhash {
my $sum = 0;
my $i = 29;
my ($div, $mod, $retval);
my ($first, $second, $string) = @_;

  chomp($string);
  unless ($first)  {printf(STDERR "NO first value!\n"); return "ERROR";}
  unless ($second) {printf(STDERR "No second value!\n"); return "ERROR";}
  unless ($string) {printf(STDERR "No user name given!\n"); return "ERROR";}
  foreach my $val ( split(//,$string) ) {
    if ( $i == 0 )  { $i = 29 };
    $sum += $prime[$i--] * ord($val);
  }
  $sum = $sum % ($first * $second);
  $div = int($sum / $second);
  $mod = int($sum % $second);


return ( $div."/".$mod );
}


-- 
        Please use PGP when replying to this message
Dr Yann Golanski                            Internet Systems Developer
PGP: http://www.kierun.org/pgp/key-planet   Mailmaster for the Planet Online