about summary refs log tree commit diff
diff options
context:
space:
mode:
authoredef <edef@edef.eu>2023-10-27T17·06+0000
committeredef <edef@edef.eu>2023-10-28T15·41+0000
commit3a77e55d2c8eab1bc3aea5dfe4da6bd6d8f9e7f0 (patch)
tree44f3eafd8ba503b428ed18c2f1772e0a7b63e721
parent2fce356ce083bd8511421499ae9eeab77f358222 (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
-rw-r--r--tvix/nix-compat/src/nixbase32.rs31
1 files changed, 15 insertions, 16 deletions
diff --git a/tvix/nix-compat/src/nixbase32.rs b/tvix/nix-compat/src/nixbase32.rs
index febc6fe598..9aed200546 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