Мне нужно повторить эту хэш-функцию x раз, но сейчас я немного растерян

#javascript #node.js #cryptography

Вопрос:

Я пытаюсь создать сценарий, который начинается с секрета, затем хэширует его и хэширует его, написанный на Javascript с узлом. Мне нужно повторить этот процесс 5 миллионов раз. Основа кода проста, но выполнение-это то, что меня замедляет. Это то, что у меня есть до сих пор.

 const secret = "Secret";  // Make the secret a const so it won't change.
var sha256 = require('sha256'); // Set-up sha256
var prehash = sha256(secret);  // Set variable 'prehash' to the hash of 'secret'
console.log(prehash);  // Display the hash
currentHash = sha256(prehash);  //Hash the previous hash
console.log(currentHash); //display the new hash
 

Мне нужно, чтобы он сделал пару вещей:

  1. Поделись секретом. (Готово)
  2. Хэш-это хэш. (Готово)
  3. Повторите это 5 миллионов раз.

Вот тут-то и возникает проблема.

Попытка решения № 1 Если я начну переназначать переменные, я потеряю представление о том, какой хэш хэшируется, так как мне приходится устанавливать для каждой итерации новый var. Это отнимает много времени, и я не могу проверить миллионы строк кода на наличие 1 переменной с ошибками только для того, чтобы обнаружить, что она была вызвана неправильно.

Попытка решения № 2 После секрета я мог бы попытаться присвоить новые хэши preHash и currentHash соответственно, но я думаю, что он устанавливает значение в строковое представление переменной, а не само значение. Вот что я имею в виду.

 var preHash = sha256(secret);
currentHash = sha256(preHash);
preHash = currentHash;
currentHash = sha256(preHash);
 

Если они происходят в таком порядке, я могу ожидать

  1. Предварительный хэш = хэш «секретно»
  2. currentHash = хэш предварительного хэша
  3. Предварительный хэш установлен равным = currentHash, что в то время означает sha256(предварительный хэш)
  4. currentHash установлен равным = sha256 нового предварительного хэша

Означает ли это, что @ шаг 3, preHash = currentHash или

Прехаш = sha256(прехаш)?

Я также изучал документы для node и js, чтобы узнать, смогу ли я;

  1. Запишите каждый вывод console.log в файл или
  2. Экспортируйте в виде CSV-файла.

Но я не смог найти ничего, что имело бы смысл.

Комментарии:

1. Почему бы не использовать рекурсивную функцию с залогами после подсчета 5 миллионов? Это был бы мой наивный подход

2. Я пришел из Python, чтобы попробовать свои силы в Javascript. Как бы вы сделали эту функцию рекурсивной. Буду ли я « выполнять функцию recurse() { currentHash = sha256(предварительная запись); Предварительная запись = текущая запись; Текущая запись = sha256(предварительная запись); рекурсия();« ?

3. Просто для ясности, является ли запрос на хэширование одного секрета 5 миллионов раз или на хэширование 5 миллионов секретов дважды? Я предполагаю, что это последнее.

4. Сначала секрет хэшируется, затем я хэширую хэш секрета и продолжаю оттуда.

5. Почему бы не использовать петлю? var hash = secret; for (var i = 0; i < 5000000; i) hash = sha256(hash);

Ответ №1:

Вот итеративное решение, которое будет продолжать передавать результаты хэша обратно в sha256 5 миллионов раз.

 const sha256 = require('sha256');
const fs = require('fs');
const secret = "Secret";
const max = 5e6; // shorthand for 5 million

let output = secret;
let hash = secret;
let i = 0;
while(i   < max){
   hash = sha256(hash);
   output  = `n${hash}`;
}

console.log('done', hash);

// save results
const fileName = "path/to/file/output.csv"; // overwrite for desired name
fs.writeFile(fileName, output, err => console.log(err));
 

Я подозреваю, что это будет очень медленно, если вы хотите отслеживать результаты каждого хэша, а затем записывать их в файл. Сначала вы должны попытаться запустить этот блок для меньших значений max и перейти оттуда. Как только вы почувствуете уверенность в этом, удалите шаги, которые создают выходную строку, и распечатайте результаты.

Комментарии:

1. Это проверяет все поля, которые мне нужны для этой функции. Я знаю, что это будет не быстро, но я ожидаю, что это займет некоторое время. Спасибо!

Ответ №2:

Предупреждение: это будет не быстро, и это всего лишь очень наивный подход

Использование pipe функции из https://www.freecodecamp.org/news/pipe-and-compose-in-javascript-5b04004ac937/ мы можем определить f(g(x)) как pipe(f,g)(x) .

Таким образом, мы можем затем использовать Array(5,000,000).fill(f) , чтобы дать нам 5 миллионов ссылок на функцию f .

Затем мы можем передать это в аргумент for pipe , и это вернет нам функцию, которая выполнит функцию f 5 миллионов раз, передавая возврат от одного к входу следующего.

 const pipe = (fns) => (x) => fns.reduce((v, f) => f(v), x);
const addOne = (x) => x 1;

const arrayOfFuncs = Array(5_000_000).fill(addOne);

const addOneChungus = pipe(arrayOfFuncs);

console.log(
  addOneChungus(0)
); 

Комментарии:

1. Это то, что, по словам моей подруги, было бы математическим эквивалентом того, что я делал, но это действительно хорошо работает в среде jsfiddle.

2. Я рад, что математик согласен со мной. Сегодня хороший день