Полный перебор символов
Уважаемые знатоки, подскажите пожалуйста как сгенерировать и запушить в массив строку состоящую из символов массива arr
var arr = ['A','B','C','D','E'] должно получится var comb = [AAAA, AAAB, AAAC..... AABA, AABB....] итд пока все не закончится строкой EEEE в общем нужен массив строк длинною в 4 символа все различно возможных комбинаций. |
VSEM-DOBRA,
перебор вариантов es6 |
рони,
Это совсем другое. тут комбинаций будет намного больше, т.к. символ может использоваться сколько угодно раз, а не один. |
VSEM-DOBRA,
Нужен массив комбинаций наподобие брутфорса пароля только из символов вашего arr? |
Цитата:
|
j0hnik,
Да Все верно =) Хелп рони, не работает <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> </head> <body> <script> function combinator(matrix){ return matrix.reduceRight(function(combination, x){ var result = []; [...x].forEach(function(a){ [...combination].forEach(function(b){ result.push(a + b); }); }); return result; }); }; document.write( JSON.stringify(combinator(['A','B','C','D','E'])) ); </script> </body> </html> =((( |
VSEM-DOBRA,
<script> "use strict" var arr = ['A','B','C','D','E']; function combinator(matrix){ return matrix.reduceRight(function(combination, x){ var result = []; [...x].forEach(function(a){ [...combination].forEach(function(b){ result.push(a + b); }); }); return result; }); }; document.write( JSON.stringify(combinator(Array.from({length : 4}, () => arr ))) ); </script> |
Первое что приходит в голову это циклы, но будет 3 вложенных цикла, не знаю насколько правильный это ход, но производительность будет максимальное (я так думаю). м.б рони возразит?
|
рони,
Красивый код =) ;) |
По мне так жуть, яб посмотрел как чувак преподу объясняет как он дошёл до такого извращения вместо простых человеческих циклов.)
|
Aetae,
А если ему потом понадобится то же самое из 6 или более символов уже пирамида упавшая на бок получится. чем жуток код рони? :( |
рони,
Спасибо работает. Aetae, мне не для препода, хучу как раз сделать что-то типа брутфорса строки. j0hnik, Тоже думал про циклы но не получилось |
VSEM-DOBRA,
все проще простого var arr = ['A','B','C','D','E'], a =[], x=[]; for(var k = 0; k<arr.length; k++){ a[0] = arr[k]; for(var l = 0; l<arr.length; l++){ a[1] = arr[l]; for(var m = 0; m<arr.length; m++){ a[2] = arr[m]; for(var n = 0; n<arr.length; n++){ a[3] = arr[n]; x.push(a.join('')); } } } } console.log(x); |
VSEM-DOBRA,
брутфорс ваш будет быстрей работать не со строками, а с массивом. и лучше не пушить, а проверять на лету и успешно забывать если не тот. 1) берем вашу строку делаем из нее массив, 2) генерируем с помощью цикла новый массив сверяем его с текущем, если не подходит, успешно забываем. если подходит останавливаем цикл. |
:write: шифровка из центра ...
<script> var arr = ['A','B','C','D','E']; function fn(e, k) { for (var f = [], c = e.length, g = 0;; g++) { var b = g.toString(c), a = k - b.length; if (0 > a) { break; } 0 < a && (b = Array(++a).join("0") + b); for (var h = "", d = 0; d < k; d++) { a = parseInt(b[d], c), h += e[a]; } f.push(h); } return f; }; document.write(fn(arr, 4).join('<br>')); </script> |
рони,
Спасибо j0hnik, Да, вы правы, буду над этим работать. |
:) :write:
<script> var arr = ['A','B','C','D','E']; function fn(e, k) { for (var f = [], c = e.length, g = 0;; g++) { var b = g.toString(c); if (b.length > k) break; b = [...b.padStart(k,"0")].reduce((a,d) => (d = parseInt(d, c), a + e[d]),""); f.push(b); } return f; }; document.write(fn(arr, 4).join('<br>')); </script> |
<script> var arr = ['A','B','C','D','E']; var x = 0; function fn(e, k) { for (var f = [], c = e.length, g = 0;; g++) { var b = g.toString(c); if (b.length > k) break; b = [...b.padStart(k,"0")].reduce((a,d) => { x++; return (d = parseInt(d, c), a + e[d]); },""); f.push(b); } console.log(x); return f; } document.write(fn(arr, 4).join('<br>')); </script> Рони, не многовато ли итераций?? как то можно ведь оптимизировать? |
j0hnik,
один цикл, куда ещё оптимальней? как преобразовать строку "0000" в "AAAA" можешь предложить своё решение, знаю только replace, не уверен что это оптимально. |
рони,
да цикл то один, а циклические методы не считаете? |
j0hnik,
<script> var arr = ['A','B','C','D','E']; function fn(e, k) { for (var f = [], c = e.length, g = 0;; g++) { var b = g.toString(c); if (b.length > k) break; b = b.padStart(k,"0").replace(/./g, d => (d = parseInt(d, c),e[d])); f.push(b); } return f; }; document.write(fn(arr, 4).join('<br>')); </script> |
toString --- поэтому длина массива не более 36, на всякий ...
|
рони,
Наверное есть более оптимальный алгоритм d = parseInt(d, c) - вот это не гуд вдруг var arr = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&`.split(''); |
рони,
Я в зал, приду напишу что нибудь полезное (если придумаю :lol: ) |
Цитата:
Цитата:
|
Можно было бы ограничиться рекурсивной переделкой варианта j0hnik:
function generate(arr, i, value, result){ if(!result){ return generate(arr, i, '', []); } if(!i--) { return result.push(value); }; for(var k = 0; k < arr.length; k++){ generate(arr, i, value + arr[k], result); } return result } console.log(generate(['A','B','C','D','E'], 4)) Но на самом деле тут просто нужно добавить капельку математики: function generate(arr, n){ var length = arr.length, result = new Array(Math.pow(length, n)); for(var i = result.length, temp = new Array(n), j; i--;){ j = n; while(j--){ temp[j] = arr[i / Math.pow(length, j) % length | 0]; } result[i] = temp.join(''); } return result } console.log(generate(['A','B','C','D','E'], 4)); |
Aetae,
j0hnik, рони, спасибо вам что помогаете, взял вот этот массив, var arr = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&`.split(''); попробовал подбирать на лету, потому что массив засоряет память до 6 символов в принципе реально подбирается. как думаете реально до 8 символов? |
Цитата:
|
рони,
я и говорю что от этого уже отошел, теперь во время уперся =( |
VSEM-DOBRA,
времени все равно много займет, зависит от проца и самого пароля, тут еще есть куда ускоряться! |
Math.pow(arr.length, длина_пароля) комбинаций;
8 для такого многовато, если пароль в конце списка и проц среднячок это пару недель. при условии доработки кода. |
Длина массива действительно ограничена, а от длины слова количество вариантов растёт экспоненциально.
Но можно лёгким движением руки превратить функцию в генератор, и получить столько значений сколько надо:): function* generate(arr, n, startIndex){ for(var length = arr.length, i = Math.pow(length, n) - (startIndex||0), temp = new Array(n), j; i--;){ j = n; while(j--){ temp[j] = arr[i / Math.pow(length, j) % length | 0]; } yield temp.join(''); } } var generator = generate(['A','B','C','D','E'], 4); alert(generator.next().value); alert(generator.next().value);Ограничены вы только временем.) |
Aetae,
пробовал ваш код в качестве генератора, но такой скорости к сожалению не дает. 7 символов еще можно, больше наверное ждать смысла нет. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> body{ width: 100%; } .wrap{ margin: 20px auto; width: 500px; } .pass{ color: red; } .time, .speed, .data, .pass, .tek, .ost{ margin: 5px 0; } </style> </head> <body> <div class="wrap"> <input type="text"> Пароль от 1 до 7 символов <br> <select> <option>1 поток</option> <option>2 потока</option> <option>3 потока</option> <option>4 потока</option> <option>5 потоков</option> <option>6 потоков</option> <option>7 потоков</option> <option>8 потоков</option> <option>9 потоков</option> <option>10 потоков</option> <option>11 потоков</option> <option>12 потоков</option> </select> <button>Старт</button> <div class="time">Время выполнения <span>0</span> сек.</div> <div class="speed">Скорость перебора <span>0</span> млн п/с</div> <div class="comb">Испытано комбинаций <span>0</span></div> <div class="tek">Текущая комбинация <span>......</span></div> <div class="ost">Оставшееся время <span>Infinity</span></div> <div class="pass"><span></span></div> </div> <script> var inp = document.querySelector('input'), sel = document.querySelector('select'), btn = document.querySelector('button'), time = document.querySelector('.time>span'), speed = document.querySelector('.speed>span'), comb = document.querySelector('.comb>span'), tek = document.querySelector('.tek>span'), ost = document.querySelector('.ost>span'), pass = document.querySelector('.pass>span'), w = [], dat = [], flag = 0, start = 0, t="*"; var workerBlobUrl = URL.createObjectURL(new Blob([workers.toString().replace(/^function .+\{?|\}$/g, '')],{type:'text/javascript'})); btn.onclick = ()=> { start = Date.now(); flag = 0, pot = sel.selectedIndex+1; w.forEach(el=>el.terminate()); for(var i = 0; i<pot; i++) w[i] = new Worker(workerBlobUrl); w.forEach((el,i)=>{ el.postMessage([inp.value, pot, i]); el.onmessage=e=>{ if(typeof e.data[0] !== 'number') { flag = 1; ps = e.data[0]; } else { dat[i]=e.data[0]; t = e.data[1].join(''); } if(flag) el.terminate(); }; }); vdata(); }; vdata=()=>{ if(flag===0){ if(dat[0]) { var c = dat.reduce((a,b)=>a + b); c = c!=NaN? c: 0; c = c!=undefined? c: dat[0]; var spd = (c/pr/1000000).toFixed(0); speed.innerHTML = spd; comb.innerHTML = c; tek.innerHTML = t; var num = [0, 62e8, 567e9, 51676e9]; var x = num.findIndex(el=>c<el); ost.innerHTML = ((c-num[x])/spd/60000000).toFixed(1)+' мин. '+(x+4)+' цифр'; } pr = ((Date.now() - start)/1000).toFixed(1); time.innerHTML = pr; setTimeout(vdata,100); } else pass.innerHTML = 'Найден пароль: '+ps.join(''); }; //worker function workers(){ self.onmessage = function(e){ var arg = e.data; p = arg[0].split(''); var arr = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-=_+[]{}:;"|<>?'/.`.split(''), w = arr.length, a = [], c = 0; var a1 = Math.floor(w/arg[1]*arg[2]); var a2 = Math.floor(w/arg[1]*(arg[2]+1)); for(var e = 0; e<=w; e++){ for(var i = 0; i<=w; i++){ for(var j = 0; j<=w; j++){ for(var k = 0; k<=w; k++){ for(var l = 0; l<=w; l++){ for(var m = 0; m<=w; m++){ for(var n = a1; n<a2; n++){a[0] = arr[n]; c++;for(var x=0,z=1;x<7;x++) if(a[x]!==p[x]){z=0; break;} if(z){self.postMessage([a]);return;} }a[1] = arr[m]; }a[2] = arr[l]; }a[3] = arr[k]; }a[4] = arr[j]; self.postMessage([c,a]); }a[5] = arr[i]; }a[6] = arr[e]; } }; } </script> </body> </html> у меня ff разгоняется до 1.3 млрд в сек |
все методы заменил на циклы процентов на 15 % стало быстрей.
|
Ну то что генераторы замедляют - оно понятно. Без генераторов просто вместо yield temp.join(''); делаешь то, что тебе нужно, self.postMessage там или ещё что. Суть в том чтобы не складывать значения в массив, а использовать сразу по назначению. Ещё капельку ускорить можно заранее сгенерировав Math.pow(length, j) для всех j.
|
Aetae,
Я их и не использовал, взял код с 26 поста и убрал все лишнее но увы =( |
function generate(arr, n){ var length = arr.length, x=0; result = new Array(Math.pow(length, n)); for(var i = result.length, temp = new Array(n), j; i--;){ j = n; while(j--){ temp[j] = arr[i / Math.pow(length, j) % length | 0]; x++; } } return x; } alert(generate(['A','B','C','D','E'], 4)); |
Мде, видать какие-то оптимизации не проходят. Даж если вообще все вычисления убрать всё равно меделеннее чем хардкод нескольких циклов. Но самое интересное, что быстрее минимум в 2 раза от хардкода работает рекурсивная версия:
https://jsperf.com/generate-brut/1 Чёртова магия.=\ |
Aetae,
Mб join убрать и посмотреть? |
Aetae,
;) |
Часовой пояс GMT +3, время: 04:57. |