ethane_types/
utils.rs

1/// Implementation taken shamelessly from
2/// [here](https://stackoverflow.com/questions/2423902/convert-an-array-of-bytes-into-one-decimal-number-as-a-string)
3pub fn bytes_to_dec_string(bytes: &[u8]) -> String {
4    let mut digits = vec![0_u8; (bytes.len() * 0x26882_usize + 0xffff_usize) >> 16];
5    let mut length = 1_usize;
6
7    for &byte in bytes.iter() {
8        let mut carry = byte as u16;
9        let mut i = 0;
10        while i < length || carry != 0 {
11            let value = digits[i] as u16 * 256_u16 + carry;
12            carry = value / 10;
13            digits[i] = (value % 10) as u8;
14            i += 1;
15        }
16        if i > length {
17            length = i
18        }
19    }
20
21    let result = digits
22        .iter()
23        .rev()
24        .skip_while(|&digit| digit == &0_u8)
25        // unwrap is fine because digit only contains numeric digits
26        .map(|&digit| std::char::from_digit(digit.into(), 10).unwrap())
27        .collect::<String>();
28    // if result = 0, all leading zeros were skipped, we have an empty string
29    if result.is_empty() {
30        "0".to_owned()
31    } else {
32        result
33    }
34}
35
36#[test]
37fn dec_string_from_bytes() {
38    assert_eq!(&bytes_to_dec_string(Vec::<u8>::new().as_slice()), "0");
39    assert_eq!(&bytes_to_dec_string(&[0][..]), "0");
40    assert_eq!(&bytes_to_dec_string(&[23][..]), "23");
41    assert_eq!(&bytes_to_dec_string(&[0, 212][..]), "212");
42    assert_eq!(&bytes_to_dec_string(&[0xfd, 0x32][..]), "64818");
43    assert_eq!(
44        &bytes_to_dec_string(&[0x23, 0x00, 0xfd, 0x32][..]),
45        "587267378"
46    );
47    assert_eq!(
48        &bytes_to_dec_string(
49            &[
50                0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE,
51                0xFF, 0x00
52            ][..]
53        ),
54        "22774453838368691933757882222884355840"
55    );
56    assert_eq!(&bytes_to_dec_string(&[0; 32][..]), "0");
57    assert_eq!(
58        bytes_to_dec_string(&u128::MAX.to_be_bytes()[..]),
59        u128::MAX.to_string()
60    );
61    // u128::MAX = 340282366920938463463374607431768211455
62    let mut u256_bytes = [0_u8; 32];
63    u256_bytes[15] = 1; // overflowing u128 by one
64    assert_eq!(
65        &bytes_to_dec_string(&u256_bytes[..]),
66        "340282366920938463463374607431768211456"
67    );
68}