[PATCH 5 of 7 V3] util: add a helper class to compute digests
Mike Hommey
mh at glandium.org
Thu Oct 16 03:22:30 CDT 2014
# HG changeset patch
# User Mike Hommey <mh at glandium.org>
# Date 1413446571 -32400
# Thu Oct 16 17:02:51 2014 +0900
# Node ID f6cbabdb852b211b67797d9775989f614ff56528
# Parent 1e45468e6b8ed9bbc77460cf9344d247c625f116
util: add a helper class to compute digests
It is going to be used for the remote-changegroup feature in bundle2.
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -112,16 +112,83 @@ def md5(s=''):
try:
from hashlib import md5 as _md5
except ImportError:
from md5 import md5 as _md5
global md5
md5 = _md5
return _md5(s)
+DIGESTS = {
+ 'md5': md5,
+ 'sha1': sha1,
+}
+# List of digest types from strongest to weakest
+DIGESTS_BY_STRENGTH = ['sha1', 'md5']
+
+try:
+ import hashlib
+ DIGESTS.update({
+ 'sha512': hashlib.sha512,
+ })
+ DIGESTS_BY_STRENGTH.insert(0, 'sha512')
+except ImportError:
+ pass
+
+for k in DIGESTS_BY_STRENGTH:
+ assert k in DIGESTS
+
+class digester(object):
+ """helper to compute digests.
+
+ This helper can be used to compute one or more digests given their name.
+
+ >>> d = digester(['md5', 'sha1'])
+ >>> d.update('foo')
+ >>> [k for k in d]
+ ['sha1', 'md5']
+ >>> d['md5']
+ 'acbd18db4cc2f85cedef654fccc4a4d8'
+ >>> d['sha1']
+ '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
+ >>> digester.preferred(['md5', 'sha1', 'sha512'])
+ 'sha512' # On python >= 2.5
+ 'sha1' # On python 2.4
+ """
+
+ def __init__(self, digests, s=''):
+ self._hashes = {}
+ for k in digests:
+ if k not in DIGESTS:
+ raise Abort(_('unknown digest type: %s') % k)
+ self._hashes[k] = DIGESTS[k]()
+ if s:
+ self.update(s)
+
+ def update(self, data):
+ for h in self._hashes.values():
+ h.update(data)
+
+ def __getitem__(self, key):
+ if key not in DIGESTS:
+ raise Abort(_('unknown digest type: %s') % k)
+ return self._hashes[key].hexdigest()
+
+ def __iter__(self):
+ return iter(self._hashes)
+
+ @staticmethod
+ def preferred(supported):
+ """returns the strongest digest type in both supported and DIGESTS."""
+
+ for k in DIGESTS_BY_STRENGTH:
+ if k in supported:
+ return k
+ return None
+
try:
buffer = buffer
except NameError:
if sys.version_info[0] < 3:
def buffer(sliceable, offset=0):
return sliceable[offset:]
else:
def buffer(sliceable, offset=0):
More information about the Mercurial-devel
mailing list