| 102 | // 实现 base58 解码 |
| 103 | impl Decoder for str { |
| 104 | fn decode_from_base58(&self) -> Result<String, DecodeError> { |
| 105 | // 保存转换字符 |
| 106 | let mut bin = [0u8; 132]; |
| 107 | let mut out = [0u32; (132 + 3) / 4]; |
| 108 | |
| 109 | // 以 4 为单位处理数据后剩余的比特数 |
| 110 | let bytes_left = (bin.len() % 4) as u8; |
| 111 | let zero_mask = match bytes_left { |
| 112 | 0 => 0u32, |
| 113 | _ => 0xffffffff << (bytes_left * 8), |
| 114 | }; |
| 115 | |
| 116 | // 统计前置 0 个数 |
| 117 | let zero_count = self.chars() |
| 118 | .take_while(|&x| x == ALPHABET_INDEX_0) |
| 119 | .count(); |
| 120 | let mut i = zero_count; |
| 121 | let b58: Vec<u8> = self.bytes().collect(); |
| 122 | while i < self.len() { |
| 123 | // 错误字符 |
| 124 | if (b58[i] & 0x80) != 0 { |
| 125 | return Err(DecodeError::InvalidCharacter(b58[i] as char, i)); |
| 126 | } |
| 127 | |
| 128 | if DIGITS_MAP[b58[i] as usize] == 255 { |
| 129 | return Err(DecodeError::InvalidCharacter(b58[i] as char, i)); |
| 130 | } |
| 131 | |
| 132 | // 进制转换 |
| 133 | let mut j = out.len(); |
| 134 | let mut c = DIGITS_MAP[b58[i] as usize] as u64; |
| 135 | while j != 0 { |
| 136 | j -= 1; |
| 137 | let t = out[j] as u64 * (BIG_RADIX as u64) + c; |
| 138 | c = (t & 0x3f00000000) >> 32; |
| 139 | out[j] = (t & 0xffffffff) as u32; |
| 140 | } |
| 141 | |
| 142 | // 数据太长 |
| 143 | if c != 0 { |
| 144 | return Err(DecodeError::InvalidLength); |
| 145 | } |
| 146 | |
| 147 | if (out[0] & zero_mask) != 0 { |
| 148 | return Err(DecodeError::InvalidLength); |
| 149 | } |
| 150 | |
| 151 | i += 1; |
| 152 | } |
| 153 | |
| 154 | // 处理剩余的比特 |
| 155 | let mut i = 1; |
| 156 | let mut j = 0; |
| 157 | bin[0] = match bytes_left { |
| 158 | 3 => ((out[0] & 0xff0000) >> 16) as u8, |
| 159 | 2 => ((out[0] & 0xff00) >> 8) as u8, |
| 160 | 1 => { |
| 161 | j = 1; |