aboutsummaryrefslogtreecommitdiff
path: root/src/base62.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/base62.rs')
-rw-r--r--src/base62.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/base62.rs b/src/base62.rs
new file mode 100644
index 0000000..6ec1e62
--- /dev/null
+++ b/src/base62.rs
@@ -0,0 +1,54 @@
+use std::iter;
+use itertools;
+
+pub const BASE: u8 = 62;
+pub const ALPHABET: &'static [u8; BASE as usize] =
+ b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+pub fn number_to_digits(mut x: u128, base: u8) -> Vec<u8> {
+ let mut out = Vec::new();
+ let base = base as u128;
+ while x > base {
+ out.push((x % base) as u8);
+ x /= base;
+ }
+ out.push(x as u8);
+ out.reverse();
+ out
+}
+
+pub fn digits_to_number<I>(x: I, base: u8) -> u128
+where I: Iterator<Item=u8> {
+ let base = base as u128;
+ x.fold(0, |out, digit| out * base + digit as u128)
+}
+
+pub fn digits_to_string<'a, I>(x: I, alphabet: &'a [u8]) -> String
+where I: Iterator<Item=u8> {
+ x.map(|d| alphabet[d as usize] as char).collect()
+
+}
+
+#[cfg(test)]
+mod test {
+ use crate::base62::*;
+
+ #[test]
+ fn test_number_to_digits() {
+ assert_eq!(vec![0], number_to_digits(0, 10));
+ assert_eq!(vec![8], number_to_digits(8, BASE));
+ assert_eq!(vec![1, 2], number_to_digits(64, BASE));
+ assert_eq!(vec![6, 4], number_to_digits(64, 10));
+ }
+
+ #[test]
+ fn test_digits_to_number() {
+ assert_eq!(digits_to_number(vec![1u8, 2].into_iter(), BASE), 64);
+ assert_eq!(digits_to_number(vec![6u8, 4].into_iter(), 10), 64);
+ }
+
+ #[test]
+ fn test_digits_to_string() {
+ assert_eq!(digits_to_string(vec![1u8, 2].into_iter(), ALPHABET), "12");
+ }
+}