Wednesday, December 4, 2013

Matching SHA1 Hashes to Torrent Hashlist

This uses the python ordered dictionary from the previous post.  Before starting the check, navigate to the directory holding the files downloaded via the torrent.  This utility is useful if you have the entire download as it does not utilize .dat files to fill in piece edges.  Running this function will return a zero indexed list of binary values that indicate pieces sha1 match status.


def HashCheck(pydict):
    '''
    This compares the hashlist in the torrent to the hashes of files in the correct directory
    Ultimately I will need some kind of db for partial files that have not been downloaded.
    '''
   
    def CheckInfo(pydict):
        '''returns list with tuples of form (filesize, relativefilepath) and last element is piece length'''
        if b'files' in pydict[b'info']:
            checkinfo = [(i[b'length'], b'/'.join(i[b'path']))  for i in pydict[b'info'][b'files'] ]
            checkinfo.append(pydict[b'info'][b'piece length'])
        else:
            checkinfo = [ (pydict[b'info'][b'length'], pydict[b'info'][b'name']), pydict[b'info'][b'piece length'] ]
        return checkinfo
   
    infolist = CheckInfo(pydict)
    remaining = infolist[-1]
    piecelist = []
    hashdex = 0
    h = hashlib.sha1()
    for fileinfo in infolist[:-1]:
        if fileinfo[0] < remaining:
            remaining -= fileinfo[0]
            f = open(fileinfo[1].decode('utf8'), 'rb')
            h.update(f.read())
            f.close()
        elif fileinfo[0] == remaining:
            remaining = infolist[-1]
            f = open(fileinfo[1].decode('utf8'), 'rb')
            h.update(f.read())
            f.close()
            hlisthash = ''.join([ell[-2:] for ell in ['0' + str(hex(el))[2:] for el in list(pydict[b'info'][b'pieces'][hashdex*20 : (hashdex + 1)*20])] ])
            print(hlisthash, h.hexdigest())
            if hlisthash == h.hexdigest():
                print('Hashes Match')
                piecelist.append(True)
            else:
                print('Bad Piece', hashdex+1)
                piecelist.append(False)
            hashdex += 1
            h = hashlib.sha1()
        elif fileinfo[0] > remaining:
            tohash = fileinfo[0]
            f = open(fileinfo[1].decode('utf8'), 'rb')
            while tohash >= remaining:
                tohash -= remaining
                h.update(f.read(remaining))
                remaining = infolist[-1]
                hlisthash = ''.join([ell[-2:] for ell in ['0' + str(hex(el))[2:] for el in list(pydict[b'info'][b'pieces'][hashdex*20 : (hashdex + 1)*20])] ])
                print(hlisthash, h.hexdigest())
                if hlisthash == h.hexdigest():
                    print('Hashes Match')
                    piecelist.append(True)
                else:
                    print('Bad Piece', hashdex+1)
                    piecelist.append(False)
                hashdex += 1
                h = hashlib.sha1()
            if tohash:
                remaining = infolist[-1] - tohash
                h.update(f.read())
               #todo: if last file, h.hexdigest() is last hash   
    return piecelist



No comments:

Post a Comment