MCPcopy Create free account
hub / github.com/QMHTMY/RustBook / decode_from_base58

Method decode_from_base58

publication/code/chapter10/base58.rs:104–192  ·  view source on GitHub ↗
(&self)

Source from the content-addressed store, hash-verified

102// 实现 base58 解码
103impl 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;

Callers

nothing calls this directly

Calls 2

lenMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected