def hash_list_values(p_list, p_key=lambda i: i):  # pragma: no branch
    """
    Calculates a unique value for each item in the list, these can be used as
    identifiers.

    The value is based on hashing an item using the p_key function.

    Suitable for lists not larger than approx. 16K items.

    Returns a tuple with the status and a list of tuples where each item is
    combined with the ID.
    """
    def to_base(p_alphabet, p_value):
        """
        Converts integer to text ID with characters from the given alphabet.

        Based on answer at
        https://stackoverflow.com/questions/1181919/python-base-36-encoding
        """
        result = ''
        while p_value:
            p_value, i = divmod(p_value, len(p_alphabet))
            result = p_alphabet[i] + result

        return result or p_alphabet[0]

    result = []
    used = set()
    alphabet = config().identifier_alphabet()

    try:
        _, size = _get_table_size(alphabet, len(p_list))
    except _TableSizeException:
        alphabet = _DEFAULT_ALPHABET
        _, size = _get_table_size(alphabet, len(p_list))

    for item in p_list:
        # obtain the to-be-hashed value
        raw_value = p_key(item)

        # hash
        hasher = sha1()
        hasher.update(raw_value.encode('utf-8'))
        hash_value = int(hasher.hexdigest(), 16) % size

        # resolve possible collisions
        while hash_value in used:
            hash_value = (hash_value + 1) % size

        used.add(hash_value)
        result.append((item, to_base(alphabet, hash_value)))

    return result
Calculates a unique value for each item in the list, these can be used as
    identifiers.

    The value is based on hashing an item using the p_key function.

    Suitable for lists not larger than approx. 16K items.

    Returns a tuple with the status and a list of tuples where each item is
    combined with the ID.