base64 uses the following logic:
/// Calculate the base64 encoded length for a given input length, optionally including any
/// appropriate padding bytes.
///
/// Returns `None` if the encoded length can't be represented in `usize`. This will happen for
/// input lengths in approximately the top quarter of the range of `usize`.
pub const fn encoded_len(bytes_len: usize, padding: bool) -> Option<usize> {
let rem = bytes_len % 3;
let complete_input_chunks = bytes_len / 3;
// `?` is disallowed in const, and `let Some(_) = _ else` requires 1.65.0, whereas this
// messier syntax works on 1.48
let complete_chunk_output =
if let Some(complete_chunk_output) = complete_input_chunks.checked_mul(4) {
complete_chunk_output
} else {
return None;
};
if rem > 0 {
if padding {
complete_chunk_output.checked_add(4)
} else {
let encoded_rem = match rem {
1 => 2,
// only other possible remainder is 2
// can't use a separate _ => unreachable!() in const fns in ancient rust versions
_ => 3,
};
complete_chunk_output.checked_add(encoded_rem)
}
} else {
Some(complete_chunk_output)
}
While base64ct does checked_mul at the beginning:
const fn encoded_len_inner(n: usize, padded: bool) -> Option<usize> {
match n.checked_mul(4) {
Some(q) => {
if padded {
Some(((q / 3) + 3) & !3)
} else {
Some((q / 3) + (q % 3 != 0) as usize)
}
}
None => None,
}
}
Since the Base64 encoding takes generally 4/3 length of the input, is it possible to relax the Encoding::encode_string's limit by reworking calculations?
cc @tarcieri
base64uses the following logic:While
base64ctdoeschecked_mulat the beginning:Since the Base64 encoding takes generally 4/3 length of the input, is it possible to relax the
Encoding::encode_string's limit by reworking calculations?cc @tarcieri