Skip to main content

shuffle_bounded

Function shuffle_bounded 

Source
pub fn shuffle_bounded(input: u64, feedback: u64, size: u64, min: u64) -> u64
Expand description

Map input into [min, min + size), visiting every value of that range exactly once per cycle.

The LFSR cannot produce zero, so the range is worked 1-based and denormalized on the way out. A register that steps past size is rejected and stepped again, which is what makes a range that is not a power of two come out whole.

§Degenerate pairs

Three pairs describe no permutation, and all three answer min, the range’s floor: the empty range below, a feedback that walks the register to zero, and one that cycles without ever landing in range. Each is reachable with the node’s own defaults or with the arbitrary constants a fuzzer supplies, so each is answered in bounded time rather than trapped. The result is always inside [min, min + size), or min when that interval is empty.

size == 0 is the empty range [min, min), which has no value to permute onto, and it is reachable without being asked for: the node’s size defaults to zero, so shuffle(x) and shuffle(x, feedback) both land here. It answers min, the range’s own floor, as hash_range answers 0 for the same degenerate bound. Left unanswered it is not merely undefined but a trap: input % size divides by zero, and were that defined the rejection loop could never terminate, since the register starts at 1 and the exit condition wants register <= 0.