Search code examples
cdelphic++builderhashcodevcl

Calculating hash MD5


I'm trying to use SubDB API but I'm having problems to calculate the hash of the file. Hash is composed by taking the first and the last 64kb of the video file, putting all together and generating a md5 of the resulting data (128kb). The following function, written in python, implements the hash algorithm:

def get_hash(name):
        readsize = 64 * 1024
        with open(name, 'rb') as f:
            size = os.path.getsize(name)
            data = f.read(readsize)
            f.seek(-readsize, os.SEEK_END)
            data += f.read(readsize)
        return hashlib.md5(data).hexdigest()

I'm using C++ Builder XE2 and I tried to translate this as follows:

String __fastcall MD5Hash(const AnsiString filename)
{
     String result;
     char firstbits[60*1024], lastbits[60*1024];
     char bits[120*1024];

     FILE* f = fopen(filename.c_str(), "rb");
     if(f ==NULL) {ShowMessage("Error!"); return "";}
     TIdHashMessageDigest5 *idmd5= new TIdHashMessageDigest5();
     try  {
        fread(firstbits, 60*1024, 1, f);
        fseek(f, -(long)60*1024, SEEK_END);
        fread(lastbits, 60*1024, 1, f);
        strcpy(bits, firstbits);
        strcpy(bits, lastbits);
        result= idmd5->HashBytesAsHex(RawToBytes(bits, 120*1024));
     }
     __finally    {
        delete idmd5;
     }
     fclose(f);
     return result;
}

Test file is this: http://thesubdb.com/api/samples/dexter.mp4, and it's hash value (from the algorithm above) should be ffd8d4aa68033dc03d1c8ef373b9028c. But, I can't get it right...

Delphi solution would be also OK.


Solution

  • How about trying the following code. I just changed the sizes, did the proper freads, and removed the strcpy.

    String __fastcall MD5Hash(const AnsiString filename)
    {
         String result;
         char bits[128*1024];
    
         FILE* f = fopen(filename.c_str(), "rb");
         if(f ==NULL) {ShowMessage("Error!"); return "";}
         TIdHashMessageDigest5 *idmd5= new TIdHashMessageDigest5();
         try  {
            fread(bits, 64*1024, 1, f);
            fseek(f, -(long)64*1024, SEEK_END);
            fread(&bits[64*1024], 64*1024, 1, f);
            result= idmd5->HashBytesAsHex(RawToBytes(bits, 128*1024));
         }
         __finally    {
            delete idmd5;
         }
         fclose(f);
         return result;
    }