It is currently 24 Apr 2024, 23:35
   
Text Size

2013 Hash file research con't'd

Moderator: CCGHQ Admins

Re: 2013 Hash file research con't'd

Postby thefiremind » 04 Sep 2012, 15:58

I would try to play around with the file, too, but I can't seem to make a (C++) program that computes and outputs the hash according to this algorithm... I think I'm using signed types that should be unsigned, or vice versa. Can someone share a piece of code that I can reuse?
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: 2013 Hash file research con't'd

Postby pcastellazzi » 04 Sep 2012, 18:06

thefiremind wrote:I would try to play around with the file, too, but I can't seem to make a (C++) program that computes and outputs the hash according to this algorithm... I think I'm using signed types that should be unsigned, or vice versa. Can someone share a piece of code that I can reuse?
Remember to force 32 bits data types. If you are using a 64 bit compiler the size of the integer will be different and the output too, due to overflows not happend when expected.
The lights then came up and the crowd erupted in applause, because that's what the crowd does after it watches destruction on a large screen.
— Ben Kuchera, Mordern Warfare 3 review.
User avatar
pcastellazzi
 
Posts: 184
Joined: 25 Apr 2012, 00:40
Location: Montevideo, Uruguay
Has thanked: 11 times
Been thanked: 30 times

Re: 2013 Hash file research con't'd

Postby RiiakShiNal » 04 Sep 2012, 21:39

thefiremind wrote:I would try to play around with the file, too, but I can't seem to make a (C++) program that computes and outputs the hash according to this algorithm... I think I'm using signed types that should be unsigned, or vice versa. Can someone share a piece of code that I can reuse?
Here is the code I'm using in C# (though it should convert to C++ fairly easily):
Code: Select all
      private UInt32 MtG2013Hash(byte[] abytData)
      {
         UInt32 nHash = 0x811C9DC5;
         for (int i = 0; i < 0x10C4; i++)
         {
            nHash *= 0x1000193;
            nHash ^= abytData[i];
         }
         return nHash;
      }
I have not yet had the code error out due to overflow, but then again I also have not yet done much testing (but I have verified it works and produces the desired result several times).

pcastellazzi wrote:Remember to force 32 bits data types. If you are using a 64 bit compiler the size of the integer will be different and the output too, due to overflows not happend when expected.
I specifically use UInt32 for this very reason (my development machine is 64-bit).
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: 2013 Hash file research con't'd

Postby thefiremind » 05 Sep 2012, 11:35

I finally made it, but the result is reversed if I compare it to hash.file contents: I get
78 9b 01 10
while hash.file contains
10 01 9b 78
Is it normal (hash.file intentionally stores the hash reversed) or am I doing something stupid?

This is my C++ code (updated), if someone is interested:
Code: Select all
#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char* argv[])
{
   if (argc < 2) // no file specified
   {
      cout << "Usage: D13Hash filename" << endl;
      return 1;
   }

   // read file
   ifstream fl(argv[1], ios_base::in | ios_base::binary | ios_base::ate);
   size_t len = fl.tellg();
   unsigned char *bytes = new unsigned char[len];
   fl.seekg(0, ios::beg);
   fl.read(bytes, len);
   fl.close();

   // compute hash
   unsigned int hash = 0x811C9DC5;
   for (int i=0; i < 0x10C4; i++)
   {
      hash *= 0x1000193;
      hash ^= bytes[i];
   }

   // free memory
   delete bytes;

   // save output in correct order
   unsigned char result[4];
   result[0] = (hash & 0xFF);
   result[1] = ((hash & 0xFF00) >> 8);
   result[2] = ((hash & 0xFF0000) >> 16);
   result[3] = ((hash & 0xFF000000) >> 24);

   // write output
   cout.flags(ios::hex);
   cout << "Length: 0x" << len << endl;
   cout << "Hash: 0x";
   for (int i=0; i<4; i++)
   {
      unsigned int output = (unsigned int)result[i];
      if (output < 16)
         cout << "0";
      cout << output;
   }
   cout << endl;

   // let the user read the result
   cout << "Press any key to end..." << endl;
   getchar();

   return 0;
}
(I'm using a 32-bit compiler so I have no need to specify it on the int type)
Last edited by thefiremind on 05 Sep 2012, 12:14, edited 1 time in total.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: 2013 Hash file research con't'd

Postby RiiakShiNal » 05 Sep 2012, 11:55

thefiremind wrote:I finally made it, but the result is reversed if I compare it to hash.file contents: I get
78 9b 01 10
while hash.file contains
10 01 9b 78
Is it normal (hash.file intentionally stores the hash reversed) or am I doing something stupid?
This is normal due to string conversions versus how things are saved.

The reason it is displaying backward for you is because you are converting it to a raw/Motorola hex string (the most significant byte is first) when writing an integer out to a file (as an integer) it is usually stored as least significant byte first (when looking at the hex this is the Intel hex display).

If you want to convert the hash to a hex string you need to take this into account like so:
Code: Select all
cout << "Hash: 0x" << (unsigned char)(hash & 0xff);
cout << (unsigned char)((hash & 0xff00) >> 8);
cout << (unsigned char)((hash & 0xff0000) >> 16);
cout << (unsigned char)((hash & 0xff000000) >> 24) << endl;
RiiakShiNal
Programmer
 
Posts: 2185
Joined: 16 May 2011, 21:37
Has thanked: 75 times
Been thanked: 497 times

Re: 2013 Hash file research con't'd

Postby thefiremind » 05 Sep 2012, 12:16

Thanks, that's exactly what I needed! I updated the code, now it displays the hash in the correct order and the program could be expanded so that it writes the hash to a file (from the "result" variable).

By the way, I think I got the right procedure yesterday, too, but without realizing that the hash was just reversed. :oops:

EDIT: I made something more complete here if someone wants to mess around with the profile without making a program of his own. :wink:
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: 2013 Hash file research con't'd

Postby spirolone » 11 Sep 2014, 16:17

I know that this is an old thread, but creating hash.file is still usefull. Even if thefiremind program is perfect, I wanted to do the same in vba code, cause I wanted an automatized procedure. I came across some problems cause there are no unsigned integer variables of 4 byte, so you can use only 31 bits and you will get a lot of overflow errors. This is my code that resolve the issue splitting 4 bytes number into two. Maybe someone can find something usefull:

Code: Select all
    'Calculating hash.file
    Dim hashL As Long       'Two Least Significant Bytes
    Dim hashH As Long       'Two Most Significant Bytes

    hashL = 40389           ' 9DC5
    hashH = 33052           ' 811C
    For i = 0 To UBound(fileContent)
        hashH = hashH * 403
        hashH = hashH + (hashL * 256)
        hashL = hashL * 403
        hashH = hashH + ((hashL And &HFFF0000) / &H10000)
        hashH = hashH And &H1000FFFF
        hashL = hashL And &H1000FFFF
        hashL = hashL Xor fileContent(i)
    Next i

    'Writing hash.file
    fileNumber = FreeFile()
    Open (filePath + "hash.file") For Binary As fileNumber
    Put fileNumber, , CByte(hashL And &H100FF)
    Put fileNumber, , CByte((hashL And &H1FF00) / &H100)
    Put fileNumber, , CByte(hashH And &H100FF)
    Put fileNumber, , CByte((hashH And &H1FF00) / &H100)
    Close fileNumber
spirolone
Programmer
 
Posts: 190
Joined: 31 Aug 2014, 23:14
Has thanked: 7 times
Been thanked: 107 times

Previous

Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 5 guests

cron

Who is online

In total there are 5 users online :: 0 registered, 0 hidden and 5 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 5 guests

Login Form