use super::bits::push_bits;
use super::mode::EncodeBits;
const ALPHANUMERIC_TABLE: &[(&str, u8)] = &[
("0", 0), ("1", 1), ("2", 2), ("3", 3), ("4", 4),
("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9),
("A", 10), ("B", 11), ("C", 12), ("D", 13), ("E", 14),
("F", 15), ("G", 16), ("H", 17), ("I", 18), ("J", 19),
("K", 20), ("L", 21), ("M", 22), ("N", 23), ("O", 24),
("P", 25), ("Q", 26), ("R", 27), ("S", 28), ("T", 29),
("U", 30), ("V", 31), ("W", 32), ("X", 33), ("Y", 34),
("Z", 35), (" ", 36), ("$", 37), ("%", 38), ("*", 39),
("+", 40), ("-", 41), (".", 42), ("/", 43), (":", 44),
];
fn char_value(c: char) -> u8 {
for (ch, val) in ALPHANUMERIC_TABLE {
if ch.chars().next() == Some(c) {
return *val;
}
}
panic!("character '{}' not in alphanumeric set", c);
}
pub fn bit_length(input: &str) -> usize {
let chars = input.chars().count();
let pairs = chars / 2;
let remainder = chars % 2;
(pairs * 11) + (remainder * 6)
}
pub fn encode(input: &str, bits: &mut EncodeBits) {
let chars: Vec<char> = input.chars().collect();
let n = chars.len();
let pairs = n / 2;
for i in 0..pairs {
let idx = i * 2;
let val1 = char_value(chars[idx]);
let val2 = char_value(chars[idx + 1]);
let combined = (val1 as u16) * 45 + (val2 as u16);
push_bits(bits, combined as u32, 11);
}
if n % 2 == 1 {
let val = char_value(chars[n - 1]);
push_bits(bits, val as u32, 6);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bit_length() {
assert_eq!(bit_length("AB"), 11); assert_eq!(bit_length("A"), 6); assert_eq!(bit_length("ABC"), 17); }
#[test]
fn test_encode_hello() {
let mut bits = EncodeBits::new();
encode("HELLO", &mut bits);
assert_eq!(bits.len(), 28);
}
}