diff options
author | edef <edef@edef.eu> | 2023-10-27T00·06+0000 |
---|---|---|
committer | edef <edef@edef.eu> | 2023-10-27T07·31+0000 |
commit | 67b08469dbaee52a622ee84757d8875f3acdee41 (patch) | |
tree | b0efa9923f9406024d36c5bb50dcd476c355544d | |
parent | 4d35a56798e8f33d758582c10a82659ac77de7ca (diff) |
refactor(tvix/nix-compat): clean up base32 decoding r/6881
Change-Id: I8591a3e1075f2281b7dc49f7fa9e0027062a78a5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9846 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/nix-compat/src/nixbase32.rs | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs index 86d900032d1a..d70e4c1a8290 100644 --- a/tvix/nix-compat/src/nixbase32.rs +++ b/tvix/nix-compat/src/nixbase32.rs @@ -52,7 +52,7 @@ pub fn encode(input: &[u8]) -> String { /// This maps a nixbase32-encoded character to its binary representation, which /// 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 { b'0'..=b'9' => encoded_char - b'0', 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]; // loop over all characters in reverse, and keep the iteration count in n. - for (n, c) in input.iter().rev().enumerate() { - match decode_char(c) { - None => return Err(Nixbase32DecodeError::CharacterNotInAlphabet(*c)), - Some(c_decoded) => { - let b = n * 5; - let i = b / 8; - let j = b % 8; - - let val = (c_decoded as u16).rotate_left(j as u32); - output[i] |= (val & 0x00ff) as u8; - let carry = ((val & 0xff00) >> 8) as u8; - - // if we're at the end of dst… - 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; - } - } + let mut carry = 0; + for (n, &c) in input.iter().rev().enumerate() { + if let Some(digit) = decode_char(c) { + let b = n * 5; + let i = b / 8; + let j = b % 8; + + let value = (digit as u16) << j; + output[i] |= value as u8 | carry; + carry = (value >> 8) as u8; + } else { + return Err(Nixbase32DecodeError::CharacterNotInAlphabet(c)); } } + // if we're at the end, but have a nonzero carry, the encoding is invalid. + if carry != 0 { + return Err(Nixbase32DecodeError::NonzeroCarry()); + } + Ok(output) } |