まあ、俺なら
1〜残り枚数分の乱数を発生
使用してない番号を記録しておく配列を作成し、そこからさきほど発生した乱数番目のデータを配置
そのデータを未使用番号配列から削除し、残り枚数のカウンタを減らす
最初に戻る
こんな感じで作るかな。これで安定してシャッフルができる。

削除する代わりにスキップさせてもいい、そっちの方が早くなるかもしれないが処理は遅いかも