Commits

Anonymous committed 38f41af

32 bits operations (not really optimized). At least we found the same results than those given as example here : http://www.zezula.net/en/mpq/techinfo.html#hashes, but not when using doctest..!

  • Participants
  • Parent commits 7111686

Comments (0)

Files changed (2)

File decryptor.py

 # -*- coding: utf-8 -*-
 
+def u32(x):
+    return x & 0xFFFFFFFFL
+
+def u32_add(a, b):
+    return u32(a + b)
+
+def u32_ls(a, b):
+    return u32(a << b)
+
 class Decryptor(object):
     def __init__(self):
         self._table = {}
                 seed = (seed * 125 + 3) % 0x2AAAAB
                 tmp2 = (seed & 0xFFFF)
                 self._table[id2] = (tmp1 | tmp2)
-                print "%d => %d" % (id2, self._table[id2])
                 cpt += 1
                 id2 += 0x100
 
             seed += self._table[0x400 + (key & 0xFF)]
 
     def hashstring(self, src, hashtype=3):
-        seed1 = 0x7FED7FED
-        seed2 = 0xEEEEEEEE
-        print "1 => %d, 2 => %d" % (seed1, seed2)
+        """Fonction de hachage utilisée pour les noms de fichiers
+
+        hashtype peut prendre les valeurs suivantes (les int):
+
+         MPQ_HASH_TABLE_OFFSET	0
+         MPQ_HASH_NAME_A	1
+         MPQ_HASH_NAME_B	2
+         MPQ_HASH_FILE_KEY	3
+
+        >>> d = Decryptor()
+        >>> d.hashstring("arr\\units.dat", 0)
+        4108764829L
+        >>> d.hashstring('unit\\neutral\\acritter.grp', 0)
+        2724227059L
+        """
+        seed1 = 0x7FED7FEDL
+        seed2 = 0xEEEEEEEEL
         for i in xrange(0, len(src)):
             ch = ord(src[i].upper())
             index = (hashtype << 8) + ch
-            seed1 = self._table[(hashtype << 8) + ch] ^ (seed1 + seed2)
-            print "seed1 => %d" % seed1
-            seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3
-            print "seed2 => %d" % seed2
-        return seed2 & 0xFFFFFFFF
+            seed1 = self._table[(hashtype << 8) + ch] ^ (u32_add(seed1, seed2))
+            seed2 = u32(ch + u32_add(seed1, seed2) + u32_ls(seed2, 5) + 3)
+        return seed1
 
 if __name__ == "__main__":
     d = Decryptor()
-    print "0x%X" % d.hashstring("arr\\units.dat", 0)
+    for f in [r"arr\units.dat", r"unit\neutral\acritter.grp"]:
+        print d.hashstring(f, 0)
+        
       temp2 = (seed & 0xFFFF);
       
       dwCryptTable[index2] = (temp1 | temp2);
-      printf("%d => %u\n", index2, dwCryptTable[index2]);
     }
   }
 }
   unsigned int seed2 = 0xEEEEEEEEL;
   int    ch;
   
-  printf("1 => %u, 2 => %u\n", seed1, seed2);
   while (*lpszString != 0) {
     ch = toupper(*lpszString++);
     seed1 = dwCryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
 
 
 int main(int argc, char **argv) {
-  const char *test = "arr\\units.dat";
+  const char *test1 = "unit\\neutral\\acritter.grp";
+  const char *test2 = "arr\\units.dat";
 
   InitializeCryptTable();
-  printf("Hash of '%s' => 0x%X\n", test, HashString(test, MPQ_HASH_TABLE_OFFSET));
+  printf("Hash of '%s' => 0x%X\n", test2, HashString(test2, MPQ_HASH_TABLE_OFFSET));
+  printf("Hash of '%s' => 0x%X\n", test1, HashString(test1, MPQ_HASH_TABLE_OFFSET));
 }