I've got a bunch of bytes I want to output in a human-friendly fashion (using characters that will be available and printable in any font/encoding/etc.). In my case, the bytes are the result of an md5 sum:
import hashlib
h = hashlib.md5("foo")
The HASH
object has two ways of displaying its contents to me.
print h.digest() # Uses a bunch of unprintable characters
print h.hexdigest() # Readable, but 32 characters long
The second option gives me a well-behaved string of characters that I can read, cut and paste, or whatever. But it's an inefficient representation: it only uses 16 characters because it's hexadecimal. It could give me a shorter string if it used the whole alphabet, uppercase letters, punctuation, etc. Can I get a shorter, denser digest by expanding beyond hex?
Here's a modified version of one of the answers to the question that @vaultah linked to:
import hashlib, string, base64
_INT_EFFICIENT_CHARS = string.letters + string.digits + string.punctuation
_L_INT_EFFICIENT_CHARS = len(_INT_EFFICIENT_CHARS)
# http://stackoverflow.com/questions/2267362/convert-integer-to-a-string-in-a-given-numeric-base-in-python
def int_efficient(x):
rets=''
while x>0:
x,idx = divmod(x, _L_INT_EFFICIENT_CHARS)
rets = _INT_EFFICIENT_CHARS[idx] + rets
return rets
h = hashlib.md5("foo")
print h.hexdigest()
# Starting in Python 3.2, use int.from_bytes rather than converting to hex
# http://stackoverflow.com/a/9634417/2829764
i = int(h.hexdigest(), 16)
print int_efficient(i)
print base64.b64encode(h.digest())
Using my alphabet (94 characters) only shortens the result by a few characters relative to base64:
acbd18db4cc2f85cedef654fccc4a4d8
Hpf=RjPL{_{4Q-[X$vdO
rL0Y20zC+Fzt72VPzMSk2A==
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.