const DIGITS: [char;62] = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; fn main() { let nums_and_bases: [(i64,i64);5] = [(10,-2),(146,-3),(15,-10),(-6222885,-62),(1488588316238,-62)]; for (n,b) in nums_and_bases.iter() { let ns = encode_neg_base(*n, *b); println!("{} encoded in base {} = {}", *n, *b, &ns); let nn = decode_neg_base(&ns, *b); println!("{} decoded in base {} = {}\n", &ns, *b, nn); } } fn decode_neg_base(ns: &str, b: i64) -> i64 { if b < -62 || b > -1 { panic!("base must be between -62 and -1 inclusive") } if ns == "0" { return 0 } let mut total: i64 = 0; let mut bb: i64 = 1; for c in ns.chars().rev() { total += (DIGITS.iter().position(|&d| d==c).unwrap() as i64) * bb; bb *= b; } return total; } fn encode_neg_base(mut n: i64, b: i64) -> String { if b < -62 || b > -1 { panic!("base must be between -62 and -1 inclusive"); } if n == 0 { return "0".to_string(); } let mut out = String::new(); while n != 0 { let mut rem = n % b; n /= b; if rem < 0 { n+=1; rem -= b; } out.push(DIGITS[rem as usize]); } return out.chars().rev().collect(); }