import sys, struct, md5 def hash(data): if data[4:12] == 'ftypM4A ': return hash_m4a(data) else: return hash_default(data) def hash_m4a(data): subatoms = [['moov'], ['trak', 'udta'], ['mdia', 'meta'], ['minf', 'ilst'], ['stbl'], [], []] atoms_to_hash = ['mdat', 'oboe', 'apID', 'atID'] hash = md5.new() def parse_data(data, depth): loc = 0 while loc < len(data): size = struct.unpack('>L', data[loc:loc+4])[0] if size == 0: atom = data[loc+4:loc+8] subdata = data[loc+8:] break atom = data[loc+4:loc+8] subdata = data[loc+8:loc+size] if atom in subatoms[depth]: if atom == 'meta': parse_data(subdata[4:], depth+1) else: parse_data(subdata, depth + 1) if atom in atoms_to_hash: hash.update(data[loc+4:loc+size]) loc += size parse_data(data, 0) return hash.hexdigest() f = file(sys.argv[1], 'rb') data = f.read() print hash(data)