diff options
author | edef <edef@edef.eu> | 2023-10-27T17·06+0000 |
---|---|---|
committer | edef <edef@edef.eu> | 2023-10-28T15·41+0000 |
commit | 3a77e55d2c8eab1bc3aea5dfe4da6bd6d8f9e7f0 (patch) | |
tree | 44f3eafd8ba503b428ed18c2f1772e0a7b63e721 /tvix/nix-compat/src | |
parent | 2fce356ce083bd8511421499ae9eeab77f358222 (diff) |
refactor(nix-compat/nixbase32): clean up encode r/6899
Change-Id: I63da5bd47cd9033e1cc13fbe4b4864514a5343cb Reviewed-on: https://cl.tvl.fyi/c/depot/+/9865 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/nix-compat/src')
-rw-r--r-- | tvix/nix-compat/src/nixbase32.rs | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs index febc6fe598ac..9aed20054602 100644 --- a/tvix/nix-compat/src/nixbase32.rs +++ b/tvix/nix-compat/src/nixbase32.rs @@ -29,24 +29,23 @@ pub fn encode(input: &[u8]) -> String { let output_len = encode_len(input.len()); let mut output = String::with_capacity(output_len); - if output_len > 0 { - for n in (0..=output_len - 1).rev() { - let b = n * 5; // bit offset within the entire input - let i = b / 8; // input byte index - let j = b % 8; // bit offset within that input byte - - let mut c = input[i] >> j; - if i + 1 < input.len() { - // we want to right shift, and discard shifted out bits (unchecked) - // To do this without panicing, we need to do the shifting in u16 - // and convert back to u8 afterwards. - c |= ((input[i + 1] as u16) << (8 - j as u16)) as u8 + for n in (0..output_len).rev() { + let b = n * 5; // bit offset within the entire input + let i = b / 8; // input byte index + let j = b % 8; // bit offset within that input byte + + // 5-bit words aren't aligned to bytes + // we can only read byte-aligned units + // read 16 bits then shift and mask to 5 + let c = { + let mut word = input[i] as u16; + if let Some(&msb) = input.get(i + 1) { + word |= (msb as u16) << 8; } + (word >> j) & 0x1f + }; - output - .write_char(ALPHABET[(c & 0x1f) as usize] as char) - .unwrap(); - } + output.write_char(ALPHABET[c as usize] as char).unwrap(); } output |