// cr16.rs - CRC16 with start 0xFFFF and POLYNOMIAL 0x1021 as used in PromptPay

use std::env;

const CRC_START: u16 = 0xffff;
const CRC_POLYNOMIAL: u16 = 0x1021;

fn crc16(data: Vec<u8>) -> u16 {
	let mut crc = CRC_START;
	let mut len = data.len();
	let mut i = 0;
	while len > 0 {
		crc ^= (data[i] as u16) << 8;
		i += 1;
		for _ in 0..8 {
			if crc & 0x8000 != 0 {
				crc = (crc << 1) ^ CRC_POLYNOMIAL;
			} else {
				crc <<= 1;
			}
		}
		len -= 1;
	}
	return crc;
}

fn main() {
	let data = match env::args().nth(1) {
		Some(str) => str,
		None => String::new(),
	};
	println!("{:04X} '{data}'\n", crc16(Vec::<u8>::from(data.clone())));
}
