@0x0000002F

Как проверить алгогитм рандома на коллизии?

Всем привет! Делаю приложение на JavaScript для шифрования текста, в котором нужна последовательность случайных чисел и каждая зависила от введенного пользователем сида. Для усложнения подбора можно выбрать алгоритм рандома из предложенных (добавленные разработчиком), а можно добавить пользовательский. Но каждый алгоритм нужно проверять на коллизии, чтобы разные сиды НЕ выдавали одинаковые последовательности.

Это не задание по написанию алгоритма. Дальше узнаете, чего я добиваюсь этим вопросом.

Да, нужен алгоритм, который от пользователя принимает:
- функцию для рандома alg(seed);
- - в свою очередь, функция принимает сид и возвращает еще одну функцию, уже которая при каждом обращении возвращает разные дробные числа, в диапазоне от 0 до 1;
- длину последовательности l;
- количество сидов n для перебора.
Алгоритм перебирает каждый сид от 0 до n, генерируя с помощью возвращенной через rand(seed) функции последовательность фиксированной длины l случайных чисел, записывая каждую в массив. После перебора, весь массив последовательностей проверяется на повторяющиеся. Если есть повторения, то алгоритм записывает в новый массив, на каких сидах они произошли. После - возвращает этот массив; если же повторений нет, то выдает пустой []
~
Я сделал свой алгоритм проверки, но не уверен, что он хороший. Так вот, как я говорил, это не "задание" по написанию алгоритма. Я лишь уточняю, хороший ли мой алгоритм, правильно ли выполняет свою задачу и можно ли как-то его улучшить.
Вот алгоритм проверки

let hum = (a, max) => Math.floor(a * max);
function check(alg, l, n) { // args (алгоритм; длина последовательности; сколько сидов проверять)
  let results = [];
  let collisions = [];
  for (let i = 0; i < n; i++) {
    let r = alg(i);
    results.push('');
    for (let j = 0; j < l; j++) {
      results[i] += hum(r(), 4096) + (j == l - 1 ? '' : ' ');
    }
  }

  for (let k = 0; k < results.length; k++) {
    let curr = results.indexOf(results[k]);
    let st = k + ' => ' + curr;
    if (curr > -1 && curr != k) collisions.push(st);
  }
  //console.log(results)
  return collisions;
}


Пример использования

function rand1(s) { // Вроде без коллизий
    let value = s;

    return function() {
        value = (value * 16807 % 2147483647) * (s ** 2);
        let _l = (''+value).length;
        return value / (10 ** _l);
    }
}
function rand2(s) { // С коллизиями
    let value = s;

    return function() {
        value = (value * 16 % 2147);
        let _l = (''+value).length;
        return value / (10 ** _l);
    }
}
let _res = check(rand1, 15, 1e4)
console.log(_res);

  • Вопрос задан
  • 109 просмотров
Пригласить эксперта
Ответы на вопрос 1
@antares4045
пойдёт? правда принимает оно строку на вход.

https://stackoverflow.com/questions/521295/seeding...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы