with Interfaces; use Interfaces;

package body Natools.Smaz.Original_Hash is

   P : constant array (0 .. 3) of Natural :=
     (1, 2, 3, 4);

   T1 : constant array (0 .. 3) of Unsigned_16 :=
     (205, 471, 343, 362);

   T2 : constant array (0 .. 3) of Unsigned_16 :=
     (421, 215, 438, 437);

   G : constant array (0 .. 508) of Unsigned_8 :=
     (19, 63, 226, 0, 0, 25, 0, 69, 0, 0, 14, 0, 0, 0, 73, 207, 92, 0, 0, 0,
      48, 0, 62, 48, 123, 56, 0, 0, 11, 47, 0, 0, 167, 145, 0, 0, 0, 213,
      114, 15, 0, 2, 214, 0, 161, 162, 0, 0, 0, 50, 0, 0, 0, 0, 0, 133, 0,
      0, 54, 0, 0, 0, 33, 220, 0, 143, 1, 0, 0, 0, 0, 229, 0, 0, 0, 0, 0,
      226, 0, 0, 110, 0, 0, 0, 209, 165, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0,
      0, 0, 79, 0, 0, 235, 0, 0, 0, 195, 237, 0, 0, 0, 0, 238, 82, 0, 252,
      26, 4, 0, 0, 205, 0, 0, 0, 0, 188, 0, 168, 0, 242, 0, 0, 0, 99, 191,
      0, 103, 0, 230, 0, 0, 0, 0, 135, 0, 183, 21, 0, 11, 172, 119, 0, 208,
      137, 0, 0, 0, 0, 0, 0, 180, 10, 183, 203, 0, 0, 86, 132, 8, 17, 0, 32,
      0, 0, 92, 0, 0, 170, 0, 0, 94, 194, 50, 185, 0, 0, 42, 0, 185, 233,
      177, 0, 0, 0, 0, 0, 0, 237, 218, 0, 0, 0, 119, 0, 181, 0, 0, 13, 0, 0,
      0, 0, 0, 0, 0, 201, 0, 42, 0, 0, 0, 0, 216, 0, 0, 0, 0, 158, 0, 0, 0,
      141, 36, 51, 0, 27, 234, 242, 0, 43, 0, 219, 78, 169, 164, 0, 59, 33,
      0, 112, 0, 31, 0, 144, 40, 0, 0, 0, 0, 0, 158, 0, 0, 0, 227, 127, 0,
      154, 241, 0, 0, 209, 0, 248, 0, 0, 68, 0, 119, 0, 0, 104, 174, 79, 0,
      0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 202, 0, 0, 0, 0, 133, 71,
      209, 189, 134, 0, 69, 0, 0, 226, 68, 0, 0, 189, 0, 230, 16, 0, 0, 0,
      0, 181, 246, 97, 0, 88, 25, 0, 49, 0, 34, 77, 30, 210, 0, 0, 0, 0,
      128, 193, 0, 116, 2, 121, 16, 0, 214, 132, 22, 116, 68, 0, 148, 0, 0,
      90, 165, 218, 157, 24, 0, 0, 192, 0, 81, 0, 0, 177, 0, 98, 81, 183, 0,
      0, 0, 0, 7, 161, 0, 123, 106, 0, 0, 136, 82, 51, 48, 0, 0, 169, 5,
      170, 138, 66, 211, 0, 112, 1, 0, 0, 84, 220, 167, 0, 0, 161, 252, 46,
      175, 95, 170, 20, 216, 177, 0, 97, 76, 44, 0, 0, 20, 0, 0, 233, 0, 0,
      0, 47, 8, 116, 147, 0, 212, 0, 0, 118, 94, 0, 89, 183, 0, 0, 105, 0,
      0, 74, 196, 28, 4, 0, 103, 0, 5, 0, 131, 45, 0, 177, 232, 219, 19,
      228, 1, 0, 31, 90, 0, 0, 150, 23, 92, 120, 238, 48, 1, 0, 0, 37, 3,
      152, 0, 0, 110, 166, 35, 13, 115, 217, 0, 0, 0, 87, 0, 126, 163, 248,
      80, 9, 12, 0, 0, 52, 10, 11, 89, 0);

   function Hash (S : String) return Natural is
      F : constant Natural := S'First - 1;
      L : constant Natural := S'Length;
      F1, F2 : Natural := 0;
      J : Natural;
   begin
      for K in P'Range loop
         exit when L < P (K);
         J  := Character'Pos (S (P (K) + F));
         F1 := (F1 + Natural (T1 (K)) * J) mod 509;
         F2 := (F2 + Natural (T2 (K)) * J) mod 509;
      end loop;
      return (Natural (G (F1)) + Natural (G (F2))) mod 254;
   end Hash;

end Natools.Smaz.Original_Hash;
