Encode input to base58check encoding.

    :param bytes val: The value to base58check encode.
    :param bytes charset: (optional) The character set to use for encoding.
    :return: the encoded bytestring.
    :rtype: bytes
    :raises: TypeError: if `val` is not bytes.

    Usage::

      >>> import base58check
      >>> base58check.b58encode(b'1BoatSLRHtKNngkdXEeobR76b53LETtpyT')
      b'\x00v\x80\xad\xec\x8e\xab\xca\xba\xc6v\xbe\x9e\x83\x85J\xde\x0b\xd2,\xdb\x0b\xb9`\xde'

def b58encode(val, charset=DEFAULT_CHARSET):
    """Encode input to base58check encoding.

    :param bytes val: The value to base58check encode.
    :param bytes charset: (optional) The character set to use for encoding.
    :return: the encoded bytestring.
    :rtype: bytes
    :raises: TypeError: if `val` is not bytes.

    Usage::

      >>> import base58check
      >>> base58check.b58encode(b'1BoatSLRHtKNngkdXEeobR76b53LETtpyT')
      b'\x00v\x80\xad\xec\x8e\xab\xca\xba\xc6v\xbe\x9e\x83\x85J\xde\x0b\xd2,\xdb\x0b\xb9`\xde'
    """

    def _b58encode_int(int_, default=bytes([charset[0]])):
        if not int_ and default:
            return default
        output = b''
        while int_:
            int_, idx = divmod(int_, base)
            output = charset[idx:idx+1] + output
        return output

    if not isinstance(val, bytes):
        raise TypeError(
            "a bytes-like object is required, not '%s', "
            "use .encode('ascii') to encode unicode strings" %
            type(val).__name__)

    if isinstance(charset, str):
        charset = charset.encode('ascii')

    base = len(charset)

    if not base == 58:
        raise ValueError('charset base must be 58, not %s' % base)

    pad_len = len(val)
    val = val.lstrip(b'\0')
    pad_len -= len(val)

    p, acc = 1, 0
    for char in deque(reversed(val)):
        acc += p * char
        p = p << 8

    result = _b58encode_int(acc, default=False)
    prefix = bytes([charset[0]]) * pad_len
    return prefix + result