Beispiel #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"
Beispiel #2
0
def exportable(blob, f_dict=None):
    """Produces something that only contains strings, lists and dicts,
    so that it can be given as input for json.dumps for instance.
    In particular:
    - convert all integers to base64
    - make sure that all elements of all lists can be dumped
    - make sure that all elements of all dictionaries can be dumped
    - convert other objects into a dictionary that can be dumped
    """
    if f_dict is None:
        f_dict = {}
    # is it an integer?
    try:
        mpz_value = mpz(blob)
    except (TypeError, ValueError):
        pass
    else:
        return utils.mpztob64(mpz_value), f_dict
    # is it a class for which we can compute a fingerprint?
    try:
        result, f_dict = blob.exportable(f_dict)
        return result, f_dict
    except AttributeError:
        pass
    # is it a string?
    if isinstance(blob, str):
        return blob, f_dict
    # is it a list?
    elif isinstance(blob, (list, tuple)):
        result = []
        for b in blob:
            e, f_dict = exportable(b, f_dict)
            result.append(e)
        return result, f_dict
    # is it a dictionary?
    elif isinstance(blob, dict):
        dict_to_export = {}
        for k in blob.keys():
            dict_to_export[k], f_dict = exportable(blob[k], f_dict)
        return dict_to_export, f_dict
    print "I cannot parse this:", blob
    assert False, "exportable cannot parse object"