Board index Programs with AI or Rules Enforcement Magic: The Gathering - Duels of the Planeswalkers Programming Talk
2013 Hash file research con't'd
Moderator: CCGHQ Admins
Re: 2013 Hash file research con't'd
by 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...
Currently busy with life...
-
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
by pcastellazzi » 04 Sep 2012, 18:06
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.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?
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.
— Ben Kuchera, Mordern Warfare 3 review.
-
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
by RiiakShiNal » 04 Sep 2012, 21:39
Here is the code I'm using in C# (though it should convert to C++ fairly easily):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?
- 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 specifically use UInt32 for this very reason (my development machine is 64-bit).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.
Just getting started: Xander9009's DotP 2014 Community Wad
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
- 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
by 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:
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;
}
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...
Currently busy with life...
-
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
by RiiakShiNal » 05 Sep 2012, 11:55
This is normal due to string conversions versus how things are saved.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?
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;
Just getting started: Xander9009's DotP 2014 Community Wad
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
Need a deck builder: DotP 2014 Deck Builder
Problems Modding: DotP 2014 Frequent Modding Mistakes
- 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
by 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.
EDIT: I made something more complete here if someone wants to mess around with the profile without making a program of his own.
By the way, I think I got the right procedure yesterday, too, but without realizing that the hash was just reversed.
EDIT: I made something more complete here if someone wants to mess around with the profile without making a program of his own.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
Currently busy with life...
-
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
by 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
22 posts
• Page 2 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 5 guests