Implement better heck encoding (not used yet)

This commit is contained in:
xenia 2020-03-13 20:28:33 -04:00
parent e042551263
commit a6d4af87ce
5 changed files with 50 additions and 22 deletions

View File

@ -4,6 +4,8 @@ all: release-build
debug-build: debug-build:
cargo build cargo build
cp ./target/debug/hptp-recv ./3700recv
cp ./target/debug/hptp-send ./3700send
release-build: release-build:
cargo build --release cargo build --release

View File

@ -7,16 +7,16 @@ lazy_static! {
static WRAP_SIZE: usize = 60; static WRAP_SIZE: usize = 60;
pub fn can_be_encoded(data: &[u8]) -> bool {
ENCODING_DETECTOR.is_match(data)
}
#[derive(Clone)] #[derive(Clone)]
pub struct MeowCoder { pub struct MeowCoder {
line_index: usize, line_index: usize,
} }
impl MeowCoder { impl MeowCoder {
pub fn can_be_encoded(data: &[u8]) -> bool {
ENCODING_DETECTOR.is_match(data)
}
pub fn new() -> MeowCoder { pub fn new() -> MeowCoder {
MeowCoder{line_index: 0} MeowCoder{line_index: 0}
} }
@ -43,7 +43,7 @@ impl MeowCoder {
(LOOKUP[first as usize], LOOKUP[second as usize]) (LOOKUP[first as usize], LOOKUP[second as usize])
} }
pub fn encode(input: &Vec<u8>) -> Vec<u8> { pub fn encode(input: &Vec<u8>) -> (Vec<u8>, bool) {
let mut out: Vec<u8> = Vec::new(); let mut out: Vec<u8> = Vec::new();
let mut prev_char: u8 = 0; let mut prev_char: u8 = 0;
let mut pair_first = false; let mut pair_first = false;
@ -61,15 +61,23 @@ impl MeowCoder {
pair_first = false; pair_first = false;
} }
} }
out // trailing byte specifies whether this was cut or not
if pair_first {
out.push(MeowCoder::hex_to_nibble(prev_char) * 16);
(out, true)
} else {
(out, false)
}
} }
pub fn decode(&mut self, input: &Vec<u8>) -> Vec<u8> { pub fn decode(&mut self, input: &Vec<u8>, was_cut: bool) -> Vec<u8> {
let mut out: Vec<u8> = Vec::new(); let mut out: Vec<u8> = Vec::new();
for byte in input { for (pos, byte) in input.iter().enumerate() {
let (first, second) = MeowCoder::u8_to_hex(*byte); let (first, second) = MeowCoder::u8_to_hex(*byte);
out.push(first); out.push(first);
if pos < input.len() - 1 || !was_cut {
out.push(second); out.push(second);
}
self.line_index += 2; self.line_index += 2;
if self.line_index == WRAP_SIZE { if self.line_index == WRAP_SIZE {
self.line_index = 0; self.line_index = 0;
@ -86,27 +94,43 @@ mod tests {
#[test] #[test]
fn test_match() { fn test_match() {
assert_eq!(can_be_encoded(b"abcd1234"), true); assert_eq!(MeowCoder::can_be_encoded(b"abcd1234"), true);
assert_eq!(can_be_encoded(b"abcXd1234"), false); assert_eq!(MeowCoder::can_be_encoded(b"abcXd1234"), false);
assert_eq!(can_be_encoded(b"012345678901234567890123456789012345678901234567890123456789\nabcdef"), true); assert_eq!(MeowCoder::can_be_encoded(b"012345678901234567890123456789012345678901234567890123456789\nabcdef"), true);
assert_eq!(can_be_encoded(b"01234567890123456789012345678901234567890123456789012345678\nabcdef"), false); assert_eq!(MeowCoder::can_be_encoded(b"01234567890123456789012345678901234567890123456789012345678\nabcdef"), false);
assert_eq!(can_be_encoded(b"\x12\xab\x45\n"), false); assert_eq!(MeowCoder::can_be_encoded(b"\x12\xab\x45\n"), false);
} }
#[test] #[test]
fn test_encode() { fn test_encode() {
let vec = vec!['a' as u8, '4' as u8, 'c' as u8, 'd' as u8, let vec = vec!['a' as u8, '4' as u8, 'c' as u8, 'd' as u8,
'\n' as u8, 'e' as u8, 'f' as u8]; '\n' as u8, 'e' as u8, 'f' as u8];
assert_eq!(MeowCoder::encode(&vec), vec![0xa4, 0xcd, 0xef]); assert_eq!(MeowCoder::encode(&vec), (vec![0xa4, 0xcd, 0xef], false));
let vec2 = vec!['a' as u8, '4' as u8, 'c' as u8, 'd' as u8,
'\n' as u8, 'e' as u8, 'f' as u8, '9' as u8];
assert_eq!(MeowCoder::encode(&vec2), (vec![0xa4, 0xcd, 0xef, 0x90], true));
} }
#[test] #[test]
fn test_encode_decode() { fn test_encode_decode() {
let hex_str: &[u8] = b"012345678901234567890123456789012345678901234567890123456789\nabcdef"; let hex_str: &[u8] = b"012345678901234567890123456789012345678901234567890123456789\nabcdef";
let vec: Vec<u8> = Vec::from(hex_str); let vec: Vec<u8> = Vec::from(hex_str);
let vec2 = MeowCoder::encode(&vec); let (vec2, was_cut) = MeowCoder::encode(&vec);
assert_eq!(was_cut, false);
let mut coder = MeowCoder::new(); let mut coder = MeowCoder::new();
let out = coder.decode(&vec2); let out = coder.decode(&vec2, was_cut);
assert_eq!(out, vec);
}
#[test]
fn test_encode_decode_cut() {
let hex_str: &[u8] = b"012345678901234567890123456789012345678901234567890123456789\nabcdef3";
let vec: Vec<u8> = Vec::from(hex_str);
let (vec2, was_cut) = MeowCoder::encode(&vec);
assert_eq!(was_cut, true);
let mut coder = MeowCoder::new();
let out = coder.decode(&vec2, was_cut);
assert_eq!(out, vec); assert_eq!(out, vec);
} }
} }

View File

@ -31,6 +31,7 @@ pub trait SerDes: Sized {
type BO = byteorder::LE; type BO = byteorder::LE;
const LAST_SEG_MASK: u32 = 1 << 31; const LAST_SEG_MASK: u32 = 1 << 31;
const MEOW_CODED_MASK: u32 = 1 << 30;
impl SerDes for UpMsg { impl SerDes for UpMsg {
fn des(buf: &[u8]) -> Result<Self, DesError> { fn des(buf: &[u8]) -> Result<Self, DesError> {
@ -39,11 +40,11 @@ impl SerDes for UpMsg {
} else { } else {
let hdr = BO::read_u32(&buf[0..4]); let hdr = BO::read_u32(&buf[0..4]);
Ok(UpMsg::Data { Ok(UpMsg::Data {
seg_idx: hdr & !LAST_SEG_MASK, seg_idx: hdr & !LAST_SEG_MASK & !MEOW_CODED_MASK,
payload: SegData { payload: SegData {
bytes: buf[4..].into(), bytes: buf[4..].into(),
is_last_segment: (hdr & LAST_SEG_MASK) != 0, is_last_segment: (hdr & LAST_SEG_MASK) != 0,
is_meow_encoded: false, is_meow_encoded: (hdr & MEOW_CODED_MASK) != 0,
}, },
}) })
} }
@ -60,7 +61,8 @@ impl SerDes for UpMsg {
}, },
seg_idx, seg_idx,
} => { } => {
let hdr = *seg_idx | if *is_last_segment { LAST_SEG_MASK } else { 0 }; let hdr = *seg_idx | if *is_last_segment { LAST_SEG_MASK } else { 0 }
| if *is_meow_encoded { MEOW_CODED_MASK } else { 0 };
BO::write_u32(&mut buf[0..4], hdr); BO::write_u32(&mut buf[0..4], hdr);
let len = bytes.len(); let len = bytes.len();
buf[4..4 + len].copy_from_slice(&bytes[..]); buf[4..4 + len].copy_from_slice(&bytes[..]);

View File

@ -50,7 +50,7 @@ pub struct SegmentSet {
#[derive(Clone)] #[derive(Clone)]
pub struct SegData { pub struct SegData {
pub(crate) bytes: Vec<u8>, pub bytes: Vec<u8>,
pub is_last_segment: bool, pub is_last_segment: bool,
pub is_meow_encoded: bool, pub is_meow_encoded: bool,
} }

View File

@ -8,5 +8,5 @@ sudo unshare -n capsh --caps="cap_net_admin+eip cap_setpcap,cap_setuid,cap_setgi
-- -c "export PATH=$PWD/.netsim:\$PATH; export HOME=$PWD; /usr/bin/ip link set lo up; netsim; \ -- -c "export PATH=$PWD/.netsim:\$PATH; export HOME=$PWD; /usr/bin/ip link set lo up; netsim; \
export PERL5LIB=\"/home/$USER/perl5/lib/perl5\${PERL5LIB:+:\${PERL5LIB}}\" \ export PERL5LIB=\"/home/$USER/perl5/lib/perl5\${PERL5LIB:+:\${PERL5LIB}}\" \
export PERL_LOCAL_LIB_ROOT=\"/home/$USER/perl5\${PERL_LOCAL_LIB_ROOT:+:\${PERL_LOCAL_LIB_ROOT}}\" \ export PERL_LOCAL_LIB_ROOT=\"/home/$USER/perl5\${PERL_LOCAL_LIB_ROOT:+:\${PERL_LOCAL_LIB_ROOT}}\" \
tc qdisc show dev lo; /bin/bash --init-file <(echo unset HISTFILE)" tc qdisc show dev lo; cd .netsim; /bin/bash --init-file <(echo unset HISTFILE)"
true true