1use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
18use scale_info::TypeInfo;
19
20#[cfg(feature = "serde_derive")]
21use serde::{Deserialize, Serialize};
22
23pub struct Bs58verify {}
25
26impl Bs58verify {
27 const BITCOIN_DECODE_MAP: [u8; 128] = [
44 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
45 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
46 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
47 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xFF, 0xFF,
48 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0xFF, 0x11,
49 0x12, 0x13, 0x14, 0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
50 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
51 0x29, 0x2A, 0x2B, 0xFF, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
52 0x37, 0x38, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
53 ];
54
55 pub fn verify(bytes: &[u8]) -> Result<(), Bs58Error> {
56 for (i, c) in bytes.iter().enumerate() {
57 if *c > 127 {
58 return Err(Bs58Error::NonAsciiCharacter(i as u8));
59 }
60
61 if Self::BITCOIN_DECODE_MAP[*c as usize] as usize == 0xFF {
62 return Err(Bs58Error::NonBs58Character(i as u8));
63 }
64 }
65 Ok(())
66 }
67}
68
69#[derive(
70 Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen,
71)]
72#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
73pub enum Bs58Error {
74 NonAsciiCharacter(u8),
76 NonBs58Character(u8),
78}