Encodes the given bytes into base16.  base16encodeb'Hello World!' '48656C6C6F20576F726C6421'  base16encodeb'HELLO WORLD!' '48454C4C4F20574F524C4421'  base16encodeb'' '' Turn the data into a list of integers where each integer is a byte, Then turn each byte into its hexadecimal representation, make sure it is uppercase, and then join everything together and return it. Decodes the given base16 encoded data into bytes.  base16decode'48656C6C6F20576F726C6421' b'Hello World!'  base16decode'48454C4C4F20574F524C4421' b'HELLO WORLD!'  base16decode'' b''  base16decode'486' Traceback most recent call last: ... ValueError: Base16 encoded data is invalid: Data does not have an even number of hex digits.  base16decode'48656c6c6f20576f726c6421' Traceback most recent call last: ... ValueError: Base16 encoded data is invalid: Data is not uppercase hex or it contains invalid characters.  base16decode'This is not base64 encoded data.' Traceback most recent call last: ... ValueError: Base16 encoded data is invalid: Data is not uppercase hex or it contains invalid characters. Check data validity, following RFC3548 https:www.ietf.orgrfcrfc3548.txt Base16 encoded data is invalid: Data does not have an even number of hex digits.  Check the character set  the standard base16 alphabet is uppercase according to RFC3548 section 6 if not setdata  set0123456789ABCDEF: raise ValueError For every two hexadecimal digits  a byte, turn it into an integer. Then, string the result together into bytes, and return it.
def base16_encode(data: bytes) -> str:
    """
    Encodes the given bytes into base16.

    >>> base16_encode(b'Hello World!')
    '48656C6C6F20576F726C6421'
    >>> base16_encode(b'HELLO WORLD!')
    '48454C4C4F20574F524C4421'
    >>> base16_encode(b'')
    ''
    """
    # Turn the data into a list of integers (where each integer is a byte),
    # Then turn each byte into its hexadecimal representation, make sure
    # it is uppercase, and then join everything together and return it.
    return "".join([hex(byte)[2:].zfill(2).upper() for byte in list(data)])


def base16_decode(data: str) -> bytes:
    """
    Decodes the given base16 encoded data into bytes.

    >>> base16_decode('48656C6C6F20576F726C6421')
    b'Hello World!'
    >>> base16_decode('48454C4C4F20574F524C4421')
    b'HELLO WORLD!'
    >>> base16_decode('')
    b''
    >>> base16_decode('486')
    Traceback (most recent call last):
      ...
    ValueError: Base16 encoded data is invalid:
    Data does not have an even number of hex digits.
    >>> base16_decode('48656c6c6f20576f726c6421')
    Traceback (most recent call last):
      ...
    ValueError: Base16 encoded data is invalid:
    Data is not uppercase hex or it contains invalid characters.
    >>> base16_decode('This is not base64 encoded data.')
    Traceback (most recent call last):
      ...
    ValueError: Base16 encoded data is invalid:
    Data is not uppercase hex or it contains invalid characters.
    """
    # Check data validity, following RFC3548
    # https://www.ietf.org/rfc/rfc3548.txt
    if (len(data) % 2) != 0:
        raise ValueError(
            """Base16 encoded data is invalid:
Data does not have an even number of hex digits."""
        )
    # Check the character set - the standard base16 alphabet
    # is uppercase according to RFC3548 section 6
    if not set(data) <= set("0123456789ABCDEF"):
        raise ValueError(
            """Base16 encoded data is invalid:
Data is not uppercase hex or it contains invalid characters."""
        )
    # For every two hexadecimal digits (= a byte), turn it into an integer.
    # Then, string the result together into bytes, and return it.
    return bytes(int(data[i] + data[i + 1], 16) for i in range(0, len(data), 2))


if __name__ == "__main__":
    import doctest

    doctest.testmod()
