old_contents: 
  import hashlib
  
  chunk_size = 9728000
  
  def md4():
  	return hashlib.new('md4')
  
  def hash_stream(stream):
  	total_md4 = None
  	while True:
  		chunk_md4 = md4()
  		chunk_left = chunk_size
  		while chunk_left:
  			n = min(chunk_left, 1024*1024)
  			part = stream.read(n)
  			chunk_md4.update(part)
  			if len(part) < n:
  				if total_md4:
  					total_md4.update(chunk_md4.digest())
  					return total_md4.hexdigest()
  				else:
  					return chunk_md4.hexdigest()
  			chunk_left -= n
  		if total_md4 is None:
  			total_md4 = md4()
  		total_md4.update(chunk_md4.digest())
  	return total_md4.hexdigest()
  
  def hash_string(s):
  	from cStringIO import StringIO
  	return hash_stream(StringIO(s))
  
  def hash_file(path):
  	with open(path, 'rb') as stream:
  		return hash_stream(stream)
  
  def test_md4():
  	assert hash_string("") == '31d6cfe0d16ae931b73c59d7e0c089c0'
  	assert hash_string("a") == 'bde52cb31de33e46245e05fbdbd6fb24'
  	assert hash_string("abc") == 'a448017aaf21d8525fc10ae87aa6729d'
  	assert hash_string("message digest") == 'd9130a8164549fe818874806e1c7014b'
  	assert hash_string("abcdefghijklmnopqrstuvwxyz") == 'd79e1c308aa5bbcdeea8ed63df412da9'
  	assert hash_string("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") == '043f8582f241db351ce627e153e7f0e4'
  	assert hash_string("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == 'e33b4ddc9c38f2199c3e7b164fcc0536'
  
  
  
  
new_contents: 
  import hashlib
  
  chunk_size = 9728000
  buffer_size = 1024*1024
  
  def md4():
  	return hashlib.new('md4')
  
  def hash_stream(stream):
  	total_md4 = None
  	while True:
  		chunk_md4 = md4()
  		chunk_left = chunk_size
  		while chunk_left:
  			n = min(chunk_left, buffer_size)
  			part = stream.read(n)
  			chunk_md4.update(part)
  			if len(part) < n:
  				if total_md4:
  					total_md4.update(chunk_md4.digest())
  					return total_md4.hexdigest()
  				else:
  					return chunk_md4.hexdigest()
  			chunk_left -= n
  		if total_md4 is None:
  			total_md4 = md4()
  		total_md4.update(chunk_md4.digest())
  	return total_md4.hexdigest()
  
  def hash_string(s):
  	from cStringIO import StringIO
  	return hash_stream(StringIO(s))
  
  def hash_file(path):
  	with open(path, 'rb') as stream:
  		return hash_stream(stream)
  
  def test_md4():
  	assert hash_string("") == '31d6cfe0d16ae931b73c59d7e0c089c0'
  	assert hash_string("a") == 'bde52cb31de33e46245e05fbdbd6fb24'
  	assert hash_string("abc") == 'a448017aaf21d8525fc10ae87aa6729d'
  	assert hash_string("message digest") == 'd9130a8164549fe818874806e1c7014b'
  	assert hash_string("abcdefghijklmnopqrstuvwxyz") == 'd79e1c308aa5bbcdeea8ed63df412da9'
  	assert hash_string("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") == '043f8582f241db351ce627e153e7f0e4'
  	assert hash_string("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == 'e33b4ddc9c38f2199c3e7b164fcc0536'
  
  
  def parse_ed2k_link(link):
  	import re
  	m = re.match(r'ed2k://\|file\|[^|]*\|(\d+)\|([a-fA-F0-9]{32})\|.*/', link)
  	if not m:
  		raise Exception('not an acceptable ed2k link: '+link)
  	file_size, hash_hex = m.groups()
  	return hash_hex, int(file_size)
  
  def verify_ed2k_link(path, link):
  	hash_hex, file_size = parse_ed2k_link(link)
  	import os.path
  	if os.path.getsize(path) != file_size:
  		return False
  	return hash_file(path) == hash_hex
  
  
  
subject: check ed2k hash