Think about data sizes. The optimal solution here is 16 bytes:
>>> hashlib.md5('thecakeisalie').digest() "'\xfc\xce\x84h\xa9\x1e\x8a\x12;\xa5\xb1K\xea\xef\xd6" >>> len(hashlib.md5('thecakeisalie').digest()) 16
The first thing you thought about was hexdigest, but it is not very close to 16 bytes:
>>> hashlib.md5('thecakeisalie').hexdigest() '27fcce8468a91e8a123ba5b14beaefd6' >>> len(hashlib.md5('thecakeisalie').hexdigest()) 32
But this will not give you ascii-encodable bytes, so we need to do something else. A simple task is to use a python view:
>>> repr(hashlib.md5('thecakeisalie').digest()) '"\'\\xfc\\xce\\x84h\\xa9\\x1e\\x8a\\x12;\\xa5\\xb1K\\xea\\xef\\xd6"' >>> len(repr(hashlib.md5('thecakeisalie').digest())) 54
We can get rid of a bunch of this by removing the "\ x" escape files and surrounding quotes:
>>> repr(hashlib.md5('thecakeisalie').digest())[1:-1].replace('\\x','') "'fcce84ha91e8a12;a5b1Keaefd6" >>> len(repr(hashlib.md5('thecakeisalie').digest())[1:-1].replace('\\x','')) 28
This is very good, but base64 does a little better:
>>> base64.b64encode(hashlib.md5('thecakeisalie').digest()) J/zOhGipHooSO6WxS+rv1g== >>> len(base64.b64encode(hashlib.md5('thecakeisalie').digest())) 24
In general, base64 is most efficient in terms of space, but I would just go with hexdigest, since it will probably be the most optimized (in terms of time).
Gnibbler's answer gives a length of 16!
>>> hashlib.md5('thecakeisalie').digest().decode("iso-8859-1") u"'\xfc\xce\x84h\xa9\x1e\x8a\x12;\xa5\xb1K\xea\xef\xd6" >>> len(hashlib.md5('thecakeisalie').digest().decode("iso-8859-1")) 16