Example #1
0
def fingerprint(blob):
    """Compute the fingerprint of its input.
       This blob can contain an integer, a string, a dict or
       an object with a fingerprint method.
    """
    # is it an integer?
    try:
        mpz_value = mpz(blob)
    except (TypeError, ValueError):
        pass
    else:
        string = utils.mpztob64(mpz_value)
        return b64encode(crypthash(string).digest())

    # is it a string?
    if isinstance(blob, str):
        return b64encode(crypthash(blob).digest())
    # is it a list?
    if isinstance(blob, (list, tuple)):
        list_of_fingerprints = [fingerprint(i) for i in blob]
        string = json.dumps(list_of_fingerprints, separators=(',', ':'))
        return b64encode(crypthash(string).digest())
    # is it a dict?
    if isinstance(blob, dict):
        # is this dict already a hash of something?
        if "#" in blob:
            return blob["#"]
        # otherwise, transform dict into array and fingerprint it
        keys = sorted(blob)
        list_of_fingerprints = [fingerprint([k, blob[k]]) \
                                    for k in keys]
        string = json.dumps(list_of_fingerprints, separators=(',', ':'))
        return b64encode(crypthash(string).digest())
    # is it None
    if blob is None:
        return fingerprint('None')
    # is it an object?
    try:
        # is it a class for which we can compute a fingerprint?
        return blob.fingerprint()
    except AttributeError:
        pass
    assert False, "fingerprint cannot parse object"
Example #2
0
 def fingerprint(self):
     """Compute the fingerprint of the object, as a base64 string.
     It tries to not recompute the same hash many times by implementing
     some tracking. However, this tracking only works for attributes.
     As a result, it will for instance not detect changes in lists or dicts.
     """
     # check whether the hash of this object is already known
     if self.attr_fingerprint["#"] is not None:
         return self.attr_fingerprint["#"]
     list_to_hash = []
     # Going through all fields that need to be taken into account
     for key in sorted(self.to_fingerprint):
         # Computing missing hashes
         if self.attr_fingerprint[key] is None:
             self.attr_fingerprint[key] = \
   fingerprint([key, getattr(self, key)])
         # Building final string
         list_to_hash.append(self.attr_fingerprint[key])
     string = json.dumps(list_to_hash, separators=(',', ':'))
     result = b64encode(crypthash(string).digest())
     self.attr_fingerprint["#"] = result
     return result