Skip to main content

codec_multibase/
decode.rs

1// SPDX-FileCopyrightText: 2026 ReallyMe LLC
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5use codec_base64url::base64url_to_bytes;
6
7use crate::{base58btc_decode, MultibaseError};
8
9/// Decode a supported multibase string to raw bytes.
10///
11/// The multibase prefix is the first Unicode scalar value, which may be
12/// more than one byte. We therefore split on a character boundary via the
13/// char iterator rather than a byte index: slicing at byte 1 would panic
14/// on any input whose first character is multi-byte (e.g. `"é"`), and this
15/// function is reached with untrusted input through
16/// [`parse_multikey`](../../multikey/index.html).
17pub fn multibase_to_bytes(multibase: &str) -> Result<Vec<u8>, MultibaseError> {
18    const MAX_MULTIBASE_INPUT_LEN: usize = codec_base64url::MAX_BASE64URL_INPUT_LEN + 1;
19    if multibase.len() > MAX_MULTIBASE_INPUT_LEN {
20        return Err(MultibaseError::InputTooLarge);
21    }
22    let mut chars = multibase.chars();
23    let prefix = chars.next().ok_or(MultibaseError::TooShort)?;
24    // The remainder of the string after the prefix character.
25    let data = chars.as_str();
26    match prefix {
27        'z' => Ok(base58btc_decode(data)?),
28        'u' => base64url_to_bytes(data).map_err(|_| MultibaseError::Base64Url),
29        _ => Err(MultibaseError::UnsupportedPrefix),
30    }
31}