Hashing/encrypting an integer to produce an unique integer in the same range
You indeed need Format-Preserving Encryption. It is a pretty easy concept, and this paper by Black and Rogaway should be readable for non-specialists. The simplest method you should be satisfied with is to use a cycle-walking cipher. Suppose :


Take $I'\leftarrow E_K(I)$;
Repeat until $I'\in [0\ldots M-1]$,


where $E_K$ is a conventional cipher with key $K$. However, the block size $n$ of $E$ should only slightly exceed $\log M$, otherwise the procedure would take too long.

If a cipher with such block length is not available, the following construction, known as Swap-or-not cipher, should help:

$E_K(X):$

for $i\leftarrow 1$ to $8 \log M$


$K_i \leftarrow AES_K(i) \pmod{M}$;
$X' \leftarrow K_i-X \pmod{M}$;
$X'' \leftarrow \max(X,X')$;
if ($F_i(K,X'')=1$) then $X \leftarrow X'$.


Here $F_i$ is some key-dependent predicate of $X''$. It must have algebraic degree or higher. For instance, it can be a polynomial of degree 2 over $F_2$, whose coefficients are encryptions of some constants by AES on the key $K$ (similarly to $K_i$).