diff --git a/src/scramble.rs b/src/scramble.rs index e7d6af6..cc3b5c1 100644 --- a/src/scramble.rs +++ b/src/scramble.rs @@ -17,41 +17,41 @@ pub fn owen(n: u32, seed: u32) -> u32 { /// of Pixels" by Ahmed et al., except using a more complete and /// efficient algorithm based on the Owen scrambling function above. pub fn z_scramble(n: u32, seed: u32) -> u32 { + const PERM_TABLE: [u8; 24] = [ + 0 | (1 << 2) | (2 << 4) | (3 << 6), // [0, 1, 2, 3], + 0 | (1 << 2) | (3 << 4) | (2 << 6), // [0, 1, 3, 2], + 0 | (2 << 2) | (1 << 4) | (3 << 6), // [0, 2, 1, 3], + 0 | (2 << 2) | (3 << 4) | (1 << 6), // [0, 2, 3, 1], + 0 | (3 << 2) | (1 << 4) | (2 << 6), // [0, 3, 1, 2], + 0 | (3 << 2) | (2 << 4) | (1 << 6), // [0, 3, 2, 1], + 1 | (0 << 2) | (2 << 4) | (3 << 6), // [1, 0, 2, 3], + 1 | (0 << 2) | (3 << 4) | (2 << 6), // [1, 0, 3, 2], + 1 | (2 << 2) | (0 << 4) | (3 << 6), // [1, 2, 0, 3], + 1 | (2 << 2) | (3 << 4) | (0 << 6), // [1, 2, 3, 0], + 1 | (3 << 2) | (0 << 4) | (2 << 6), // [1, 3, 0, 2], + 1 | (3 << 2) | (2 << 4) | (0 << 6), // [1, 3, 2, 0], + 2 | (0 << 2) | (1 << 4) | (3 << 6), // [2, 0, 1, 3], + 2 | (0 << 2) | (3 << 4) | (1 << 6), // [2, 0, 3, 1], + 2 | (1 << 2) | (0 << 4) | (3 << 6), // [2, 1, 0, 3], + 2 | (1 << 2) | (3 << 4) | (0 << 6), // [2, 1, 3, 0], + 2 | (3 << 2) | (0 << 4) | (1 << 6), // [2, 3, 0, 1], + 2 | (3 << 2) | (1 << 4) | (0 << 6), // [2, 3, 1, 0], + 3 | (0 << 2) | (1 << 4) | (2 << 6), // [3, 0, 1, 2], + 3 | (0 << 2) | (2 << 4) | (1 << 6), // [3, 0, 2, 1], + 3 | (1 << 2) | (0 << 4) | (2 << 6), // [3, 1, 0, 2], + 3 | (1 << 2) | (2 << 4) | (0 << 6), // [3, 1, 2, 0], + 3 | (2 << 2) | (0 << 4) | (1 << 6), // [3, 2, 0, 1], + 3 | (2 << 2) | (1 << 4) | (0 << 6), // [3, 2, 1, 0], + ]; + let mut result = 0; for i in 0..16 { let mask = if i < 15 { (!0) << ((i + 1) * 2) } else { 0 }; - let entry = (hash_u32(n & mask, seed) % 24) as usize; - let cell = ((n >> (i * 2)) & 0b11) as usize; - result |= (Z_TABLE[entry][cell] as u32) << (i * 2); + let perm_entry = PERM_TABLE[(hash_u32(n & mask, seed) % 24) as usize]; + let perm_cell_i = ((n >> (i * 2)) & 0b11) as usize; + result |= (((perm_entry >> (perm_cell_i * 2)) & 0b11) as u32) << (i * 2); } result } - -const Z_TABLE: &[[u8; 4]; 24] = &[ - [0, 1, 2, 3], - [0, 1, 3, 2], - [0, 2, 1, 3], - [0, 2, 3, 1], - [0, 3, 1, 2], - [0, 3, 2, 1], - [1, 0, 2, 3], - [1, 0, 3, 2], - [1, 2, 0, 3], - [1, 2, 3, 0], - [1, 3, 0, 2], - [1, 3, 2, 0], - [2, 0, 1, 3], - [2, 0, 3, 1], - [2, 1, 0, 3], - [2, 1, 3, 0], - [2, 3, 0, 1], - [2, 3, 1, 0], - [3, 0, 1, 2], - [3, 0, 2, 1], - [3, 1, 0, 2], - [3, 1, 2, 0], - [3, 2, 0, 1], - [3, 2, 1, 0], -];