affinidi_encoding/
multibase.rs1use crate::EncodingError;
9use crate::multicodec::MultiEncoded;
10
11pub const BASE58BTC_PREFIX: char = 'z';
13
14pub fn decode_base58btc(s: &str) -> Result<Vec<u8>, EncodingError> {
18 let Some(encoded) = s.strip_prefix(BASE58BTC_PREFIX) else {
19 let prefix = s.chars().next().unwrap_or('\0');
20 return Err(EncodingError::InvalidMultibasePrefix(prefix));
21 };
22
23 bs58::decode(encoded)
24 .into_vec()
25 .map_err(|e| EncodingError::InvalidBase58(e.to_string()))
26}
27
28pub fn encode_base58btc(bytes: &[u8]) -> String {
30 format!("{}{}", BASE58BTC_PREFIX, bs58::encode(bytes).into_string())
31}
32
33pub fn validate_base58btc(s: &str) -> Result<(), EncodingError> {
35 decode_base58btc(s)?;
36 Ok(())
37}
38
39pub fn decode_multikey(key: &str) -> Result<Vec<u8>, EncodingError> {
44 let bytes = decode_base58btc(key)?;
45 let multi_encoded = MultiEncoded::new(&bytes)?;
46 Ok(multi_encoded.data().to_vec())
47}
48
49pub fn decode_multikey_with_codec(key: &str) -> Result<(u64, Vec<u8>), EncodingError> {
51 let bytes = decode_base58btc(key)?;
52 let multi_encoded = MultiEncoded::new(&bytes)?;
53 Ok((multi_encoded.codec(), multi_encoded.data().to_vec()))
54}
55
56pub fn encode_multikey(codec: u64, key_bytes: &[u8]) -> String {
61 let encoded = crate::multicodec::MultiEncodedBuf::encode_bytes(codec, key_bytes);
62 encode_base58btc(encoded.as_bytes())
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_decode_base58btc() {
71 let result = decode_base58btc("zCn8eVZg").unwrap();
73 assert_eq!(result, b"hello");
74 }
75
76 #[test]
77 fn test_encode_base58btc() {
78 let encoded = encode_base58btc(b"hello");
79 assert_eq!(encoded, "zCn8eVZg");
80 }
81
82 #[test]
83 fn test_roundtrip() {
84 let original = b"test data for encoding";
85 let encoded = encode_base58btc(original);
86 let decoded = decode_base58btc(&encoded).unwrap();
87 assert_eq!(decoded, original);
88 }
89
90 #[test]
91 fn test_invalid_prefix() {
92 let result = decode_base58btc("fABCDEF"); assert!(matches!(
94 result.unwrap_err(),
95 EncodingError::InvalidMultibasePrefix('f')
96 ));
97 }
98
99 #[test]
100 fn test_invalid_base58() {
101 let result = decode_base58btc("z0OIl");
103 assert!(matches!(
104 result.unwrap_err(),
105 EncodingError::InvalidBase58(_)
106 ));
107 }
108
109 #[test]
110 fn test_did_key_identifier() {
111 let id = "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK";
113 let result = decode_base58btc(id);
114 assert!(result.is_ok());
115 let bytes = result.unwrap();
116 assert_eq!(bytes[0], 0xed);
118 }
119}