SHA1 in Torque
by Kyrah Abattoir · 04/08/2013 (5:28 pm) · 5 comments
This is resource will allow you to add to the engine the ability to produce SHA1 hashes and expose it to TorqueScript.
I want to give a BIG thank to the people at irc.maxgaming.net #garagegames , especially Tim-MGT and TRON who fixed my many rookie errors, without them I would never have managed to make it work.
EDIT: I added a second function to compute SHA1 digests on files, it's probably not the best way to load and read the file, but it will work even with very large files (about 5 seconds on my system for a 400Mb file) without having to load it in memory.
EDIT: I modified the file function to use a larger buffer a more elegant while loop, and removed the buffer pointer.
Grab sha1.cc and sha1.h from gauss.ececs.uc.edu/Courses/c653/lectures/Hashing/sha1/
Place both files wherever it is convenient for you, personally i'm using the existing source folder in my project folder.
"My Projects/<projectname>/source/sha1/"
In visual C++ Open the solution explorer section "<projectname> DLL".
I tend to keep my files separated from the "core" files whenever i can, so in my case, i created a new filter si it looks like this:
"Source Files/<project>/sha1/" and then i added both sha1.cc and sha1.h to it. As far as i know the tree view in the solution explorer is only for "visual" tidyness.
There are numerous uses for such a hashing function, such as message signing, authentication systems and integrity checks.
Enjoy!
I want to give a BIG thank to the people at irc.maxgaming.net #garagegames , especially Tim-MGT and TRON who fixed my many rookie errors, without them I would never have managed to make it work.
EDIT: I added a second function to compute SHA1 digests on files, it's probably not the best way to load and read the file, but it will work even with very large files (about 5 seconds on my system for a 400Mb file) without having to load it in memory.
EDIT: I modified the file function to use a larger buffer a more elegant while loop, and removed the buffer pointer.
Step 1: getting the algorythm
Grab sha1.cc and sha1.h from gauss.ececs.uc.edu/Courses/c653/lectures/Hashing/sha1/
Place both files wherever it is convenient for you, personally i'm using the existing source folder in my project folder.
"My Projects/<projectname>/source/sha1/"
Step 2: Including it in the project
In visual C++ Open the solution explorer section "<projectname> DLL".
I tend to keep my files separated from the "core" files whenever i can, so in my case, i created a new filter si it looks like this:
"Source Files/<project>/sha1/" and then i added both sha1.cc and sha1.h to it. As far as i know the tree view in the solution explorer is only for "visual" tidyness.
Step 3: Exposing it to TorqueScript
In The solution explorer i created a new file "console_functions.cc". This is basically the "glue" that enable you to access the SHA1 code from the engine.#include "console/engineAPI.h" //This is mandatory to get access to DefineConsoleFunction.
#include "sha1/sha1.h" //You might need to change this to reflect where you placed your sha1.h file.
//This function turn the binary returned by the sha1 hashing in exadecimal form
static char getHex(char c)
{
if(c <= 9)
return c + '0';
return c - 10 + 'A';
}
//The actual TorqueScript function.
DefineConsoleFunction( getStringSHA1, const char*, ( const char* text ),,
"Generate SHA1 hash of string." )
{
const size_t hashSize = 20;
sha1_context ctx;
unsigned char sha1sum[hashSize];
char *strhash;
size_t i;
// generate hash
sha1_starts(&ctx);
sha1_update(&ctx,(uint8 *)text, strlen(text));
sha1_finish(&ctx, sha1sum);
// get a string buffer to hold hash value to return to caller
strhash = Con::getReturnBuffer( (U32)(hashSize * 2) +1 );
strhash[hashSize * 2] = 0;
// convert hash sum into hexadecimal string
for(i=0; i<hashSize; ++i)
{
strhash[i*2 ] = getHex(sha1sum[i] >> 4 );
strhash[i*2 +1] = getHex(sha1sum[i] & 0x0F);
}
// return hash string to caller
return strhash;
}
DefineConsoleFunction( getFileSHA1, const char*, ( const char* filepath ),,"Generate SHA1 hash of a file." )
{
const size_t hashSize = 20;
const size_t buffSize = 32000;
sha1_context ctx;
unsigned char sha1sum[hashSize];
char *strhash;
size_t i;
size_t size;
char buffer[buffSize];
//we open the file, if the file couldn't be opened, we return NULL.
FILE * myFile = fopen(filepath,"rb");
if(myFile == NULL)
{
Con::errorf(ConsoleLogEntry::Script, "File not found: \"%s\".",filepath);
return NULL;
}
sha1_starts(&ctx);
while( true )
{
//as long as we haven't reached the end of the file, we loop.
size = fread(buffer, 1, buffSize, myFile);
sha1_update(&ctx,(uint8 *)buffer, size);
if(size < buffSize) break;
}
sha1_finish(&ctx, sha1sum);
// get a string buffer to hold hash value to return to caller
strhash = Con::getReturnBuffer( (U32)(hashSize * 2) +1 );
strhash[hashSize * 2] = 0;
// convert hash sum into hexadecimal string
for(i=0; i<hashSize; ++i)
{
strhash[i*2 ] = getHex(sha1sum[i] >> 4 );
strhash[i*2 +1] = getHex(sha1sum[i] & 0x0F);
}
// return hash string to caller
return strhash;
}Step 4: Using it!
The syntax to call this function is the following:%hashedtext = getStringSHA1( %text );And to get the sha1 checksum on a file:
%hashedfile = getFileSHA1( %filepath );NOTE: Trying to sha a file that doesn't exist will return null.
There are numerous uses for such a hashing function, such as message signing, authentication systems and integrity checks.
Enjoy!
About the author
3D artist, programmer, game designer, jack of all trades, master of none.
#2
04/09/2013 (2:43 pm)
File hashing added :)
#3
04/11/2013 (6:03 am)
Nice addition thanks.
#5
05/09/2013 (2:23 am)
You realize that's a gpl implementation of SHA-1 you're using, right? The original public domain implementation of the algorithm can be found here: http://www.faqs.org/rfcs/rfc3174.html 
Torque 3D Owner JeffH