refactor(tvix/nix-compat): clean up base32 decoding

Change-Id: I8591a3e1075f2281b7dc49f7fa9e0027062a78a5
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9846
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
This commit is contained in:
edef 2023-10-27 00:06:01 +00:00
parent 4d35a56798
commit 67b08469db

View file

@ -52,7 +52,7 @@ pub fn encode(input: &[u8]) -> String {
/// This maps a nixbase32-encoded character to its binary representation, which /// This maps a nixbase32-encoded character to its binary representation, which
/// is also the index of the character in the alphabet. /// is also the index of the character in the alphabet.
fn decode_char(encoded_char: &u8) -> Option<u8> { fn decode_char(encoded_char: u8) -> Option<u8> {
Some(match encoded_char { Some(match encoded_char {
b'0'..=b'9' => encoded_char - b'0', b'0'..=b'9' => encoded_char - b'0',
b'a'..=b'd' => encoded_char - b'a' + 10_u8, b'a'..=b'd' => encoded_char - b'a' + 10_u8,
@ -69,31 +69,26 @@ pub fn decode(input: &[u8]) -> Result<Vec<u8>, Nixbase32DecodeError> {
let mut output: Vec<u8> = vec![0x00; output_len]; let mut output: Vec<u8> = vec![0x00; output_len];
// loop over all characters in reverse, and keep the iteration count in n. // loop over all characters in reverse, and keep the iteration count in n.
for (n, c) in input.iter().rev().enumerate() { let mut carry = 0;
match decode_char(c) { for (n, &c) in input.iter().rev().enumerate() {
None => return Err(Nixbase32DecodeError::CharacterNotInAlphabet(*c)), if let Some(digit) = decode_char(c) {
Some(c_decoded) => { let b = n * 5;
let b = n * 5; let i = b / 8;
let i = b / 8; let j = b % 8;
let j = b % 8;
let val = (c_decoded as u16).rotate_left(j as u32); let value = (digit as u16) << j;
output[i] |= (val & 0x00ff) as u8; output[i] |= value as u8 | carry;
let carry = ((val & 0xff00) >> 8) as u8; carry = (value >> 8) as u8;
} else {
// if we're at the end of dst… return Err(Nixbase32DecodeError::CharacterNotInAlphabet(c));
if i == output_len - 1 {
// but have a nonzero carry, the encoding is invalid.
if carry != 0 {
return Err(Nixbase32DecodeError::NonzeroCarry());
}
} else {
output[i + 1] |= carry;
}
}
} }
} }
// if we're at the end, but have a nonzero carry, the encoding is invalid.
if carry != 0 {
return Err(Nixbase32DecodeError::NonzeroCarry());
}
Ok(output) Ok(output)
} }