Если вам нужен криптографически безопасный способ сделать это, вы можете проверить мою статью о Криптографически безопасных перестановках с блочными шифрами . В двух словах, выберите блочный шифр, используйте технику, называемую сворачиванием XOR, чтобы уменьшить его до наименьшей степени 2, превышающей желаемый диапазон, а затем используйте следующую технику, чтобы генерировать только числа в желаемом диапазоне:
def permute(index, max):
index = E(index)
if index > max:
return permute(index, max)
То есть просто «зашифруйте» любое сгенерированное вами число, выходящее за пределы желаемого диапазона. Объем работы, необходимый для генерации всей последовательности, ограничен количеством элементов в исходной последовательности. Худший случай для генерации одного элемента - 1 + unused_range, но это невероятно малая вероятность.
Вы можете применить это ко всему, что генерирует отображение 1: 1, конечно, не только к примеру блочного шифра. И если вы имеете дело с другим видом ГСЧ - например, LFSR, вместо повторного применения функции, просто пропустите этот элемент.