#!/usr/bin/env python # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ This module implements the eDonkey2000 hash algorithm It can be imported and used by other code or run as a standalone hasher (printing ed2k links for the indicated files) """ import hashlib from zlib import crc32 def ed2khash(fname,crc=False): '''Hash the specified file, returning (size,hash) or (size,hash,crc32sum) An ed2k hash is computed by hashing each 9728000 byte chunk using MD4 then hashing the combination of those hashes. If crc is true, also compute the crc32 sum of the file ''' f = open(fname,'rb') hashes = '' protohasher = hashlib.new('md4') buf = '42' c = 0 while True: buf = f.read(9728000) if (buf == ''): break hasher = protohasher.copy() hasher.update(buf) hashes += hasher.digest() if crc: c = crc32(buf,c) if f.tell() > 9728000: hasher = protohasher.copy() hasher.update(hashes) hash = hasher.hexdigest() if crc: return (f.tell(),hash,c&0xffffffff) else: return (f.tell(),hash) def ed2klink(fpath, e): 'Generate an ed2k link from the path and (size,hash) tuple' import os.path (size,hash) = e fname = os.path.split(fpath)[1] link = 'ed2k://|file|%s|%d|%s|/' % (fname,size,hash) return link if __name__=='__main__': import sys for f in sys.argv[1:]: try: print ed2klink(f,ed2khash(f)) except: sys.stderr.write("Failed to hash %s\n" % (f))