..
基于Rust的Base58实现
看一段之前用 Rust
实现的代码。
impl <'a> Encode for BaseX <'a>{
type Output = String;
fn encode(&self, source: &[u8]) -> String {
let base = self.alphabet.len() as u16;
let mut digits: Vec<u16> = vec![0u16; 1];
let mut i = 0;
while i < source.len() {
let mut j = 0;
let mut carry: u16 = source[i] as u16;
let digits_len = digits.len();
while j < digits_len {
carry += digits.as_slice()[j] << 8;
digits.as_mut_slice()[j] = carry % (base as u16);
carry = (carry / (base as u16)) | 0;
j += 1;
}
while carry > 0 {
digits.push(carry % (base as u16));
carry = (carry / base) | 0;
}
i += 1;
}
let mut string = "".to_string();
// deal with leading zeros
let mut k = 0;
while source[k] == 0 && k < source.len() - 1 {
string.push(self.alphabet[0] as char);
k += 1;
}
// convert digits to a string
let mut q: i32 = (digits.len() - 1) as i32;
while q >= 0 {
let uu: u8 = self.alphabet[digits[q as usize] as usize];
let xx = uu as char;
string.push( xx );
q -= 1;
}
string
}
}
encode
算法就走三步实现了。
步骤
第一步 辗转除58,求余数
第二步 处理0的情况
第三步 查表
decode
就是个反过程,很简单的小算法。
在进行地址编码的时候, 各家使用的table情况也不一样, 看一下常见的几个。
pub const BITCOIN: &[u8; 58] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
pub const RIPPLE: &[u8; 58] = b"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz";
pub const FLICKR: &[u8; 58] = b"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
pub const SKYWELL: &[u8; 58] = b"jpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65rkm8oFqi1tuvAxyz";
格外说两句
小算法的应用,有成就感。 3
-
Base58 is Base64 without the number 0 (zero), O (capital letter O), l (small L), I (large i), and the characters “+” and “/”. Or, simply put, it is a set of uppercase and lowercase letters and numbers without the four (0, O, L, I) mentioned above. ↩