1use std::str::{self};
2use rand::Rng;
3use utcnow::utcnow;
4use base64::{Engine as _, engine::general_purpose};
5use crate::constants::*;
6
7pub(crate) fn milliseconds_now() -> i64 {
9 let ts = utcnow().unwrap().as_millis();
10 let max = i64::MAX;
11 if ts <= max as i128 {
12 ts as i64
13 } else {
14 max
15 }
16}
17
18pub(crate) fn from_base_36(sample: &str) -> Option<Vec<u8>> {
19 if sample.len() > 0 {
20 base_encode::from_str(sample, 36, BASE_36_CHARS)
21 } else {
22 None
23 }
24}
25
26pub(crate) fn from_base_16(sample: &str) -> Option<Vec<u8>> {
27 base_encode::from_str(sample, 16, HEX_CHARS)
28}
29
30pub(crate) fn base_36_parts_to_hex_dec(sample: &str) -> Option<String> {
31 if let Some(values) = from_base_36(sample) {
32 base_encode::to_string(&values, 16, HEX_CHARS)
33 } else {
34 None
35 }
36}
37
38pub(crate) fn hex_dec_to_base_36(sample: &str) -> Option<String> {
39 if let Some(values) = from_base_16(sample) {
40 base_encode::to_string(&values, 36, BASE_36_CHARS)
41 } else {
42 None
43 }
44}
45
46pub(crate) fn dec_to_base_36(value: u32) -> Option<String> {
48 let buf = value.to_be_bytes();
49 base_encode::to_string(&buf, 36, BASE_36_CHARS)
50}
51
52pub(crate) fn i64_to_base_36(value: i64) -> Option<String> {
54 let buf = value.to_be_bytes();
55 base_encode::to_string(&buf, 36, BASE_36_CHARS)
56}
57
58pub(crate) fn base_36_to_u8(letter: &char) -> Option<u8> {
60 if let Some(values) = from_base_36(&letter.to_string()) {
61 if values.len() > 0 {
62 if let Some(value) = values.last() {
63 Some(*value)
64 } else {
65 None
66 }
67 } else {
68 None
69 }
70 } else {
71 None
72 }
73}
74
75pub(crate) fn base_36_str_to_u64(sample: &str) -> Option<u64> {
76 if let Some(values) = from_base_36(sample) {
77 let radix: u64 = 256;
78 let num_values = values.len();
79 let max_36_pow = 12;
80 if num_values > 0 {
81 let max_pow = if num_values < max_36_pow { values.len() - 1 } else { max_36_pow };
82 let mut curr_pow = max_pow as u32;
83 let mut sum: u64 = 0;
84 for v in values {
85 let multiplier = if curr_pow > 0 { radix.pow(curr_pow) } else { 1u64 };
86 sum += v as u64 * multiplier;
87 if curr_pow > 0 {
88 curr_pow -= 1;
89 }
90 }
91 Some(sum)
92 } else {
93 None
94 }
95 } else {
96 None
97 }
98}
99
100pub(crate) fn random_int(max: u32) -> u32 {
101 let mut rng = rand::thread_rng();
102 rng.gen::<u32>() % max
103}
104
105pub(crate) fn rand_char(characters: &[char]) -> char {
106 let len = characters.len();
107 let rand_index = random_int(len as u32) as usize;
108 characters.get(rand_index).unwrap_or(&' ').to_owned()
109}
110
111pub(crate) fn rand_char_as_string(rand_chars: &[char]) -> String{
112 rand_char(rand_chars).to_string()
113}
114
115pub(crate) fn rand_int_36(power: u8) -> String {
116 let max = 10u32.pow(power as u32);
117 let rand_int = random_int(max);
118 dec_to_base_36(rand_int).unwrap_or("".to_string())
119}
120
121pub(crate) fn hex_string_to_base36_parts(hex_str: &str) -> Option<String> {
123 if hex_str.len() >= MIN_VALID_UUID_LENGTH {
124 let base36_str = vec![&hex_str[..12],&hex_str[12..]].into_iter()
125 .map(|hd| hex_dec_to_base_36(hd).unwrap_or("".to_string()))
126 .collect::<Vec<String>>()
127 .join("_");
128 Some(base36_str)
129 } else {
130 None
131 }
132}
133
134pub fn encode_base64(key_str: &str) -> String {
136 general_purpose::STANDARD.encode(key_str)
137}
138
139pub fn decode_base64(sample: &str) -> String {
141 let decoded = general_purpose::STANDARD.decode(sample).unwrap_or(vec![]);
142 str::from_utf8(&decoded).unwrap_or("").to_string()
143}