I was wondering how Fisher-Yates is correct, and decided to write my own proof, before looking for others, and it seems a little more simplistic but like it also might work. The code I'm working with is:
for i from 1 to N:
j = Equilikely(i, N)
swap(T[i], T[j])
done
Proof that given an initial array T, with elements $a_1...a_N$, each element has a $1/N$ probability of ending up at the end of the algorithm at any index $1...N$. (To me this should be sufficient, I see a lot of proofs focusing on the probability of the whole permutation).
First, when $i=1$, since j=Equilikely(1,N), and we swap $i$ with $j$, each of the original elements $a_1...a_N$ has a probability of $1/N$ of ending up in slot 1. Since slot 1 is never considered again and can't be modified, this stays the same for the rest of the algorithm.
Second, we assume by induction that for $1\leq{} k\lt{} i$ each element $a_1...a_N$ has a $1/N$ probability of ending up in slot $k$. The probability of an $a_k$ from the original array not being in slots $1...(i-1)$ is
$$ \begin{align*} 1 - \sum_{1\leq{} k \lt{} i} 1/N \\ = \frac{N-i+1}{N} \end{align*} $$
Now at the beginning of loop $i$ when we make the assignment j = Equilikely(i, N), we choose from among $N-i+1$ items to set slot $i$ to. So the probability of any of the original items ending up in slot $i$ is the probability of it being in slots $i...N$ and it being chosen:
$$ \begin{align*} &\frac{1}{N-i+1}\cdot{}\frac{N-i+1}{N} \\ &=1/N \end{align*} $$
This completes the proof by induction, each original element has a probability of $1/N$ of being in any given slot of the final array.