Factory to create hash functions from configuration section. If an
    algorithm takes custom parameters, you can separate them by a colon like
    this: pbkdf2:arg1:arg2:arg3.

def new(conf):
    """Factory to create hash functions from configuration section. If an
    algorithm takes custom parameters, you can separate them by a colon like
    this: pbkdf2:arg1:arg2:arg3."""

    algorithm = conf.get("algorithm")
    salt = conf.get("salt").encode("utf-8")

    if algorithm == "none":
        return Hash(salt, None)
    elif algorithm.startswith("pbkdf2"):
        kwargs = {}
        tail = algorithm.partition(":")[2]
        for func, key in ((int, "iterations"), (int, "dklen"), (str, "func")):
            head, _, tail = tail.partition(":")
            if not head:
                break
            kwargs[key] = func(head)

        return PBKDF2(salt, **kwargs)
    else:
        return Hash(salt, algorithm)