Is possible to recover the `u16` from the bytes?

This is the u16 -> [u8; 2] algorithm.

let prefix = u16::from(network);
let mut bytes = match prefix {
	0..=63 => vec![prefix as u8],
	64..=16_383 => {
		let first = ((prefix & 0b0000_0000_1111_1100) as u8) >> 2;
		let second = ((prefix >> 8) as u8) | ((prefix & 0b0000_0000_0000_0011) as u8) << 6;

		vec![first | 0b01000000, second]
	},
	_ => Err(Error::UnsupportedNetwork(network.into()))?,
};

I'm not sure if this is a reversible algorithm.

u16 has to_be_bytes and from_be_bytes methods (and little endian versions) that you can use if you aren't doing anything other than splitting it into bytes

2 Likes

OP is definitely doing a lot more than that. From what I can understand, the conversion is lossy, since if prefix >= 64, then the bottom 2 bits are removed from first. Then, the bottom two bits are slapped onto the 8th and 9th bit (counting from 0) with OR, and the whole thing is shifted down by 8 positions, creating second.

I think it isn't reversible. Since you are OR'ing the 0th and 1st bit onto the 8th and 9th bit respecively, that loses information.

2 Likes
  • Bits 2..8 end up in 0..6
  • Bits (0..2 | 8..10) end up in 6..8
  • Bits 10..16 end up in 8..14

So it's not uniquely reversible.

2-bit result possible two 2-bit inputs
00 00 00
01 01 00, 00 01, 01 01
10 10 00, 00 10, 10 10
11 00 11, 01 11, 10 11, 11 11, 10 01, 11 01, 01 10, 11 10, 11 00
5 Likes