You can use a modified affine cipher chain. It's the type of design I developed initially when trying to find a way to scramble database IDs, or name-based / time-based GUIDs without introducing birthday collisions.
Given that you want to express all non-negative integers smaller than $n = 2048$, $n$ is the exclusive maximum, and $m = n-1$ is the inclusive maximum. All those numbers can be expressed in $L = |m|$ number of bits, which in this case $L = 11$ bits. Then, find the first prime number $P_n \ge 2^{L}$, here that would be $P_n = 2053$.
Choose a uniform, random key $k \in \{0, 1\}^{7 \cdot L}$ and slice it into seven equal $L$-size, non-overlapping chunks $k_0$, $k_1$, $k_2$, $k_3$, $k_4$, $k_5$, $k_6$, and convert each of those keys into non-negative integers. Now, $k_3$ and $k_5$ (the multiplication keys) do also need to be non-zero, so you can resample randomly from $\{0, 1\}^L$ until those two don't end up converting into zeros. Then the random-ish, bijective permutation $f_{k,n}(x)$ will be defined like this:
$$\forall k' \space (k' \gt 0)$$
$$g_{k',k''}(x) = y = (k' \cdot x + k'') \mod P_n$$
$$G_{k',k''}(x) = \begin{cases} G_{k',k''}(y) & \text{if } y \ge 2^L \\ y & \text{otherwise} \end{cases}$$
$$f_{k,n}(x) = G_{k_5,k_6}(G_{k_3,k_4}(x \oplus k_0) \oplus k_1) \oplus k_2$$
Because the prime number $P_n$ is larger than the desired range, we have to shrink the range using a recursive definition for $G_{k',k''}(x)$. It uniquely swaps an element $x$ such that $g_{k',k''}(x) \leftrightarrow y$ where $x \lt 2^L$ and $P_n \gt y \ge 2^L$, with another element $x' = y$ such that $g_{k',k''}(x') \leftrightarrow y'$ where $P_n \gt x' \ge 2^L$ and $y' \lt 2^L$.
For small domains, it's probably worthwhile to increase $C$, the chain of calls to $G_{k',k''}(x)$ within $f_{k,n}(x)$. That's if a keyspace larger than $77$ bits is desired, or a better chance at good random-ish scrambling. The formula $\space |k| = (3 \cdot C + 1) \cdot L \space$ can determine how long a string of bits $k$ will need to be for a chain of calls of length $C$. In my testing on larger domains (where $n \ge 2^{128}$), a chain of length $C \ge 2$ was enough to produce random looking outputs, and break up the obvious bit patterns that are present from only a single call to $G$.
This solution is:
- Efficiently computable: Processing each input $x$ would cost about three xors, and an average of two multiplications, two additions and two modulo reductions.
- Bijective: It might not be obvious, but each input $x$ will map to a unique output $y$. It's easier to see by considering if each operation is bijective. If each operation is bijective, then the chain of operations is bijective.
- Small in area: It would take about 77 bits to store the key $k$, and 12 bits to store the prime $P_n$. In total that would be 89 bits.
- Simple to implement: The capacity to perform xor, multiplication and addition modulo a number is ubiquitous. The most challenging operation would be changing the domain of your problem and then determining the next prime number $P_n \ge 2^L$.
- Length preserving: Each permutation result $f_{k,n}(x)$ will fit in the same amount of bits defined by the inclusive maximum number $m$ in your problem domain.
As long as you don't need actual encryption, this could help.