def b58encode(val, charset=DEFAULT_CHARSET):
    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