Fonction exponentiation modulaire


Cette fonction calcule

H(K) = ( cK mod d )  mod m

K est la clef, c et d des entiers qu'il faut choisir judicieusement et m la taille de la table.

On prendra la clef comme étant un grand entier plutôt qu'une série d'octets. Fort heureusement pour nous, il existe un algorithme très efficace pour calculer l'exponentiation, et mieux encore, les exponentiations mod d. Si on considère que la clef est un grand entier storé en mémoire en commençant par l'octet le moins significatif (LSB first, ou small endian) on obtient l'implémentation efficace suivante:





 inline unsigned 
 HashModularExp(const unsigned char *buffer, 
                    int size)
  {
   unsigned s = 1u;
   unsigned y = 7u;
   const unsigned M = 1234567891u; // ~1G

   for (int i=0; i<size; i++)
    {
     unsigned p = buffer[i];
    
     while (p)
      {
       if (p & 1) s = (s*y) % M;
       y = (y*y) % M;
       p >>= 1;
      }
    }

   return s;
  }




Cette fonction est, en pratique, assez forte bien qu'elle puisse souffrir du même problème que la fonction de hash multiplicative: si la variable y tombe à zéro, elle agit comme élément absorbant et le résultat global est zéro. Cependant, en choisissant jusdicieusement c et d on minimise sérieusement les chances que cela se produise; en pratique même, on ne remarque pas l'effet de façon significative.




( steven.pigeon@videotron.ca )