Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Полный перебор символов (https://javascript.ru/forum/misc/73637-polnyjj-perebor-simvolov.html)

VSEM-DOBRA 02.05.2018 15:47

Полный перебор символов
 
Уважаемые знатоки, подскажите пожалуйста как сгенерировать и запушить в массив строку состоящую из символов массива arr

var arr = ['A','B','C','D','E']


должно получится

var comb = [AAAA, AAAB, AAAC..... AABA, AABB....]

итд пока все не закончится строкой EEEE

в общем нужен массив строк длинною в 4 символа все различно возможных комбинаций.

рони 02.05.2018 16:00

VSEM-DOBRA,
перебор вариантов es6

VSEM-DOBRA 02.05.2018 16:04

рони,
Это совсем другое. тут комбинаций будет намного больше, т.к. символ может использоваться сколько угодно раз, а не один.

j0hnik 02.05.2018 16:09

VSEM-DOBRA,
Нужен массив комбинаций наподобие брутфорса пароля только из символов вашего arr?

рони 02.05.2018 16:14

Цитата:

Сообщение от VSEM-DOBRA
Это совсем другое

это то что вам нужно, будет массив из 625 строк от AAAA до EEEE

VSEM-DOBRA 02.05.2018 16:22

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>


=(((

рони 02.05.2018 16:24

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>

j0hnik 02.05.2018 16:25

Первое что приходит в голову это циклы, но будет 3 вложенных цикла, не знаю насколько правильный это ход, но производительность будет максимальное (я так думаю). м.б рони возразит?

j0hnik 02.05.2018 16:27

рони,
Красивый код =) ;)

Aetae 02.05.2018 16:37

По мне так жуть, яб посмотрел как чувак преподу объясняет как он дошёл до такого извращения вместо простых человеческих циклов.)

j0hnik 02.05.2018 16:40

Aetae,
А если ему потом понадобится то же самое из 6 или более символов уже пирамида упавшая на бок получится.

чем жуток код рони? :(

VSEM-DOBRA 02.05.2018 16:43

рони,
Спасибо работает.

Aetae,
мне не для препода, хучу как раз сделать что-то типа брутфорса строки.

j0hnik,
Тоже думал про циклы но не получилось

j0hnik 02.05.2018 16:56

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);

j0hnik 02.05.2018 17:02

VSEM-DOBRA,
брутфорс ваш будет быстрей работать не со строками, а с массивом.
и лучше не пушить, а проверять на лету и успешно забывать если не тот.

1) берем вашу строку делаем из нее массив,
2) генерируем с помощью цикла новый массив сверяем его с текущем, если не подходит, успешно забываем. если подходит останавливаем цикл.

рони 02.05.2018 17:08

: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>

VSEM-DOBRA 02.05.2018 17:47

рони,
Спасибо
j0hnik,
Да, вы правы, буду над этим работать.

рони 02.05.2018 18:08

:) :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>

j0hnik 02.05.2018 18:21

<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>


Рони, не многовато ли итераций??
как то можно ведь оптимизировать?

рони 02.05.2018 18:30

j0hnik,
один цикл, куда ещё оптимальней?
как преобразовать строку "0000" в "AAAA" можешь предложить своё решение, знаю только replace, не уверен что это оптимально.

j0hnik 02.05.2018 18:33

рони,
да цикл то один, а циклические методы не считаете?

рони 02.05.2018 18:37

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>

рони 02.05.2018 18:40

toString --- поэтому длина массива не более 36, на всякий ...

j0hnik 02.05.2018 18:49

рони,
Наверное есть более оптимальный алгоритм

d = parseInt(d, c) - вот это не гуд
вдруг
var arr = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&`.split('');

j0hnik 02.05.2018 18:56

рони,
Я в зал, приду напишу что нибудь полезное (если придумаю :lol: )

рони 02.05.2018 19:00

Цитата:

Сообщение от j0hnik
вдруг

Цитата:

Сообщение от рони
toString --- поэтому длина массива не более 36, на всякий ...

любой бред длиной меньше 36.

Aetae 02.05.2018 20:17

Можно было бы ограничиться рекурсивной переделкой варианта 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));

VSEM-DOBRA 02.05.2018 20:56

Aetae,
j0hnik,
рони,

спасибо вам что помогаете,

взял вот этот массив,

var arr = `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&`.split('');


попробовал подбирать на лету, потому что массив засоряет память
до 6 символов в принципе реально подбирается.

как думаете реально до 8 символов?

рони 02.05.2018 21:25

Цитата:

Сообщение от VSEM-DOBRA
потому что массив засоряет память

может вам массив и не нужен? получили строку, проверили, сгенерировали следующий вариант.

VSEM-DOBRA 02.05.2018 21:31

рони,
я и говорю что от этого уже отошел, теперь во время уперся =(

j0hnik 02.05.2018 21:34

VSEM-DOBRA,
времени все равно много займет, зависит от проца и самого пароля, тут еще есть куда ускоряться!

j0hnik 02.05.2018 21:39

Math.pow(arr.length, длина_пароля) комбинаций;
8 для такого многовато, если пароль в конце списка и проц среднячок это пару недель. при условии доработки кода.

Aetae 02.05.2018 21:42

Длина массива действительно ограничена, а от длины слова количество вариантов растёт экспоненциально.
Но можно лёгким движением руки превратить функцию в генератор, и получить столько значений сколько надо:):
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);
Ограничены вы только временем.)

j0hnik 02.05.2018 23:07

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 млрд в сек

j0hnik 02.05.2018 23:10

все методы заменил на циклы процентов на 15 % стало быстрей.

Aetae 02.05.2018 23:28

Ну то что генераторы замедляют - оно понятно. Без генераторов просто вместо yield temp.join(''); делаешь то, что тебе нужно, self.postMessage там или ещё что. Суть в том чтобы не складывать значения в массив, а использовать сразу по назначению. Ещё капельку ускорить можно заранее сгенерировав Math.pow(length, j) для всех j.

j0hnik 02.05.2018 23:37

Aetae,
Я их и не использовал, взял код с 26 поста и убрал все лишнее но увы =(

j0hnik 02.05.2018 23:44

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));

Aetae 03.05.2018 00:36

Мде, видать какие-то оптимизации не проходят. Даж если вообще все вычисления убрать всё равно меделеннее чем хардкод нескольких циклов. Но самое интересное, что быстрее минимум в 2 раза от хардкода работает рекурсивная версия:
https://jsperf.com/generate-brut/1
Чёртова магия.=\

j0hnik 03.05.2018 00:48

Aetae,
Mб join убрать и посмотреть?

j0hnik 03.05.2018 00:58

Aetae,
;)


Часовой пояс GMT +3, время: 04:57.