1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::error::Error;
use sha2::{Digest, Sha256};
mod base58check_config;
use base58check_config::Base58CheckConfig;
#[cfg(test)]
mod tests;
pub fn encode_b58c_plain(source: Vec<u8>) -> Result<String, Box<dyn Error>> {
let b_config = Base58CheckConfig::default();
if source.len() <= 0 { return Ok("".to_string()); }
let mut zeroes: usize = 0;
let mut length: usize = 0;
let mut pbegin: usize = 0;
let pend = source.len();
while pbegin != source.len() && source[pbegin] == 0 {
pbegin += 1;
zeroes += 1;
}
let size = ((pend as f64 - pbegin as f64) * b_config.i_factor + 1.0) as u64 >> 0;
let mut b58: Vec<u8> = vec![0; size as usize];
while pbegin != pend {
let mut carry = source[pbegin] as u64;
let mut it1 = (size - 1) as i64;
let mut i = 0 as usize;
while (carry != 0 || i < length) && it1 != -1 {
carry += (256.0 * b58[it1 as usize] as f64) as u64 >> 0;
let carry_mod_base = (carry as f64 % b_config.base as f64) as u64 >> 0;
b58[it1 as usize] = carry_mod_base as u8;
carry = ((&carry / b_config.base) as f64) as u64 >> 0;
it1 = &it1 - 1;
i = &i + 1;
}
if carry != 0 {
panic!("carry is non-zero: c{} b{} i{} l{} b{} e{}", &carry, b58[it1 as usize], &i, &length, &pbegin, &pend);
}
length = i.to_owned();
pbegin += 1;
}
let mut it2 = (size as u64) - (length as u64);
while it2 != size && b58[it2 as usize] == 0 {
it2 += 1;
}
let mut str_leader = (format!("{}", b_config.leader)).as_str().repeat(zeroes);
while it2 < size {
it2 += 1;
let str_slice = format!("{}", b_config.alphabet_vec[b58[it2 as usize - 1 as usize] as usize]);
str_leader = format!("{}{}", &str_leader, &str_slice);
}
Ok(str_leader)
}
fn double_sha256(payload: &[u8]) -> Vec<u8> {
let hasher = Sha256::new().chain_update(&payload);
let output: Vec<_> = hasher.finalize().into_iter().collect();
let hasher = Sha256::new().chain_update(&output);
hasher.finalize().into_iter().collect()
}
pub fn encode(payload: Vec<u8>) -> Result<String, Box<dyn Error>> {
let payload_u8a: &[u8] = &*payload;
let checksum = double_sha256(payload_u8a);
let mut the_buffer: Vec<u8> = vec![0; payload.len() + 4];
let xx = payload_u8a.len();
let ii = 0;
for i in ii..xx {
the_buffer[i] = payload_u8a[i];
}
the_buffer[ xx + 0] = checksum[0];
the_buffer[ xx + 1] = checksum[1];
the_buffer[ xx + 2] = checksum[2];
the_buffer[ xx + 3] = checksum[3];
encode_b58c_plain(the_buffer)
}