Показать полную графическую версию : Вопрос по скрипту для генерации паролей.
1947792 - число комбинаций... »вы посчитали размещение без повторений »
Это результат расчета количества сочетаний.
Busla, а вот тут вопрос — как именно трактовать авторское:
без повторов »
:).
Почему 1000 в секунду? »
:dont-know , где-то попалась на глаза цифра, вот и подумалось...
так как набор символов неисчерпаем »
Хмм, это чего? набор из 36 символов - что тут неисчерпаемого, поясните?
надо посчитать, сколько чисел содержится в диапазоне от 000000 до 999999. »
Считаем: раз два три четыре пять .... МИЛЬЁН! (если приплюсовать 000000) »
комбинаторика - раздел математики, следовательно наука точная. Если результаты не сходятся, значит в наличии ошибка... либо в формулах (что маловероятно, ибо доказываются), либо в расчетах (что гораздо более вероятно).
При анализе, достаточно ясно вырисовывается картинка, что за основу расчетов была взята формула не предполагающая наличие повторов символов, в этом моя ошибка.
В общем, формула выбрана неверно, следовательно, количество допустимых сочетаний комбинаций будет ещё больше...
Смотрим:
function get-factorial([int]$num = 1) {
switch ($num -le 1) {
$true { $num }
$false {$num*(get-factorial(--$num))}
}
}
$n = '0123456789abcdefghijklmnopqrstuvwxyz'
$m = 6
# количество уникальных сочетаний C = n!/m!*(n-m)!
$C = (get-factorial $n.length)/((get-factorial $m)*(get-factorial ($n.length - $m)))
$C
# количество неуникальных сочетаний C = (n+m-1)!/m!*(n-1)!
$Cr = (get-factorial ($n.length + $m - 1))/((get-factorial $m)*(get-factorial ($n.length - 1)))
$Cr
# количество уникальных размещений A = n!/(n-m)!
$A = (get-factorial $n.length)/(get-factorial ($n.length - $m))
$A
# количество неуникальных размещений A = n^m
$Ar = [math]::pow($n.length,$m)
$Ar
И получаем 2176782336 - неуникальных размещений.
Козьма Прутков, конечно же, совершенно прав. :)
Кстати, если длина строки =2 (00 - 99) Ваш скрипт декларирует 90. - что-то в консерватории надо менять. »
Поменяем и получим то, что и должно быть - 100, просто находили мы не то, что следовало из-за ошибочного выбора формулы... :)
прав, вы посчитали размещение без повторений »
совершенно верно... пока писал ответ с перерывами на обед, тут уже всё разжевали без меня... :)
Ну да и пусть тоже будет...
как именно трактовать авторское »
в самом широком смысле, то есть - как душе угодно :)
Поэтому, видимо и требуются все варианты...
как именно трактовать »
Так как речь идет о паролях, то по логике подразумевается уникальность(отсутствие повторов) самих паролей, что бы пароль от аккаунта Пети на подошел к аккаунту Коли.
Так, например, код из поста 5все комбинации перебора строки»0..99 | foreach { (New-Guid).Guid.Substring(0,6) }сработает неверно для имеющейся задачи, так как выдаст неуникальные значения:$pass=0..1296 | foreach { (New-Guid).Guid.Substring(0,2) }
cls
"Повторов: "+($pass.Count-($pass|sort -U).count)
#~Повторов: 1042
Повторы символов внутри пароля не влияют на его уникальность(ab != aa).
Хмм, это чего? набор из 36 символов - что тут неисчерпаемого, поясните? »
Исчерпаемый пул:
Набор символов - материальные шары в корзине. Если мы взяли шар с буквой 'a' в качестве первого символа, то в корзине его больше нет, и на месте второго символа он уже не окажется.
Так мы получим 1 402 410 240 вариантов.
Неисчерпаемый пул:
Набор символов - набор символов в переменной. Если мы взяли букву 'a' в качестве первого символа, то из переменной она никуда не пропадает, следовательно имеет возможность оказаться на месте и второго символа.
Так мы получим 2 176 782 336 вариантов.
Неисчерпаемый пул »
Мысль понял, спасибо.
Foreigner
13-05-2020, 12:52
Fors1k_m
$pass=0..1296 | foreach { (New-Guid).Guid.Substring(0,2) }
А если в подстроку взять только первый символ, как скоро он повторится?
0..1296 | % { (New-Guid).Guid.Substring(0,6) } | group | ? Count -gt 1
Не возвращает ни одной группы. Потому, что они все, 1297 групп, из одного элемента
0..1296 | % { (New-Guid).Guid.Substring(0,6) } | group | ? Count -gt 1Не возвращает ни одной группы. Потому, что они все, 1297 групп, из одного элемента »
1296 - это максимальное количество вариантов для комбинации из двух символов.(Код для проверки (http://forum.oszone.net/post-2920945-18.html))
Так что либо нужно считать для комбинаций из двух:
cls;0..1296 | % { (New-Guid).Guid.Substring(0,2) } | group | ? Count -gt 1
Либо для комбинации из шести добавьте хотя бы один нолик количеству вариантов:
cls;0..12960 | % { (New-Guid).Guid.Substring(0,6) } | group | ? Count -gt 1
cls;0..12960 | % { (New-Guid).Guid.Substring(0,6) } | group | ? Count -gt 1
Count Name Group
----- ---- -----
2 14a6c0 {14a6c0, 14a6c0}
2 6c8ceb {6c8ceb, 6c8ceb}
2 f75d25 {f75d25, f75d25}
2 4d6e03 {4d6e03, 4d6e03} У меня вышло 4 повтора.
Foreigner
13-05-2020, 13:57
1296 - это максимальное количество вариантов для комбинации из двух символов »
Это не перебор символов, из множества а их генерация. Естественно, что они могут повторяться. К тому же это лишь подстрока GUID (32 символа без дефисов).
12961 вариант из шести символов выдал три повтора, две сотых процента. Но это важно вообще? Возьми из массива только уникальные елементы.
Foreigner
13-05-2020, 14:19
Pади интереса:
0..12960 | % { (get-random $([char[]]'0123456789abcdefghijklmnopqrstuvwxyz') -count 6) -join '' } | group | ? count -gt 1
Не выдал повторов с шести попыток.
Естественно, что они могут повторяться.
..это важно вообще? »
Конечно важно, так как:
1. Я уже говорил (http://forum.oszone.net/post-2920965-24.html) о фундаментальном смысле уникальности паролей.
2. Такую задачу четко поставил автор:
необходимо сгенерировать пароли без повторов »
Возьми из массива только уникальные елементы. »
Это не решит задачу:
необходимо сгенерировать все возможные пароли»
Pади интереса:
0..12960 | % { (get-random $([char[]]'0123456789abcdefghijklmnopqrstuvwxyz') -count 6) -join '' } | group | ? count -gt 1
Не выдал повторов с шести попыток. »
Если монетка 9 раз упала орлом вверх орлом, это не значит, что на десятый бросок не будет решки.
Pади интереса:$rep=0;$k=0
while($rep -lt 1){$k++
$pass=1..12960|foreach { (get-random $([char[]]'0123456789abcdefghijklmnopqrstuvwxyz') -count 6) -join '' }
$rep=($pass.Count-($pass|sort -U).count)
}
"Первый повтор встречается на $k попытке"
Первый повтор встречается на 11 попытке
megaloman
13-05-2020, 19:28
... а вот тут вопрос — как именно трактовать авторское: Цитата SoulGood:без повторов »и все возможные комбинации. Имхо, ушли от темы: обсуждаем число комбинаций и рандомную генерацию. Я до сих пор понимал полный набор символов от 000000 до zzzzzz, однако тут звучит идея, что в строке не должно быть повторяющихся символов. Есть ли эффективный алгоритм получения такого набора? @Echo Off
Set "Simb=0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"
rem Set "Simb=0 1 2 3 4 5 6 7 8 9"
Set "FileOut=Z:\Box_Out\FileOut.txt
>"%FileOut%" (
Call Echo %%time%%
For %%i In (%Simb%) Do (
For %%j In (%Simb%) Do (
If Not %%j==%%i For %%k In (%Simb%) Do (
If Not %%k==%%i If Not %%k==%%j For %%l In (%Simb%) Do (
If Not %%l==%%i If Not %%l==%%j If Not %%l==%%k For %%m In (%Simb%) Do (
If Not %%m==%%i If Not %%m==%%j If Not %%m==%%k If Not %%m==%%l For %%n In (%Simb%) Do (
If Not %%n==%%i If Not %%n==%%j If Not %%n==%%k If Not %%n==%%l If Not %%n==%%m Echo %%i%%j%%k%%l%%m%%n
)
)
)
)
)
)
Call Echo %%time%%
)
Exit /B
20:05:18,03
012345
012346
012347
012348
012349
012354
.....
987645
987650
987651
987652
987653
987654
20:05:34,92
151200 строкДля 36 символов не берусь оценить время
Вообще-то задача достаточно бессмысленая, разве что как лаба. Практически надо генерировать пароль рандомным образом для каждого конкретного случая, и вероятность того, что пароли совпадут, достаточно низкая
генерировать пароль рандомным образом для каждого конкретного случая, и вероятность того, что пароли совпадут, достаточно низкая »
правильно
@echo off
set "nA=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
set "l=6"&:[длина пароля]
set "n=10"&:[количество вариантов]
set "f=keys.log"
setlocal enabledelayedexpansion
for /l %%n in (1 1 %n%) do (
for /l %%n in (1 1 %l%) do call :#
>>"%f%" echo:
)
endlocal
pause& exit
:#
set /a r=%random%%%36
set "s=!nA:~%r%,1!"
>>"%f%" <nul set /p=%s%
exit /b
Есть ли эффективный алгоритм получения такого набора? »
param(
$pathOut = 'C:\temp\test.txt',
$symbols = '0123456789'
)cls
$file=New-Object IO.StreamWriter ([IO.File]::Open($pathOut,'Create'))
[string[]]$sym=$symbols.ToCharArray()
(Measure-Command{
foreach($a in $sym){
foreach($b in (diff $sym ($a)).InputObject){
foreach($c in (diff $sym ($a,$b)).InputObject){
foreach($d in (diff $sym ($a,$b,$c)).InputObject){
foreach($e in (diff $sym ($a,$b,$c,$d)).InputObject){
foreach($f in (diff $sym ($a,$b,$c,$d,$e)).InputObject){
$file.Writeline("$a$b$c$d$e$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций: $i"
По скорости получается 8,03 сек.
По скорости получается 8,03 сек »
если только цифры, то можно так https://rosettacode.org/wiki/Combinations#PowerShell
для [Powershell.CSharp]::Combinations(6,10)
TotalMilliseconds : 72,4355
megaloman
14-05-2020, 17:53
По скорости получается 8,03 сек. »Все познаётся в корректном сравнении на одной и той же машине.
На моём суперкомпе Ваш код делается 13', мой - 17', (http://forum.oszone.net/post-2921009-32.html) слегка его соптимизировал - 9'@Echo Off
Set "S=0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"
Set "S=0 1 2 3 4 5 6 7 8 9"
Set "FileOut=Z:\Box_Out\FileOutNew.txt"
SetLocal EnableExtensions EnableDelayedExpansion
>"%FileOut%" (
Call Echo %%time%%
For %%i In (%S%) Do (
Set "S1=!S:%%i=!" &For %%j In (!S1!) Do (
Set "S2=!S1:%%j=!" &For %%k In (!S2!) Do (
Set "S3=!S2:%%k=!" &For %%l In (!S3!) Do (
Set "S4=!S3:%%l=!" &For %%m In (!S4!) Do (
Set "S5=!S4:%%m=!" &For %%n In (!S5!) Do Echo %%i%%j%%k%%l%%m%%n
)
)
)
)
)
Call Echo %%time%%
)
Exit /BСсылку от YuS_2 не рассматривал - по условию в общем случае символы могут быть не обязательно цифры
Foreigner
15-05-2020, 02:37
Прямой перебор по индексу:
$y = 6 # длина комбинации
$x = 0..9 # количество элементов
[array] $code = "for (`$c0 = 0; `$c0 -le $($y - 1); `$c0++) {"
for ($i = 1; $i -le ($y - 1); $i++)
{
$code += "for (`$c$i = 0; `$c$i -le $($x.count-1); `$c$i++) {"
}
$res =
for ($i = 0; $i -le ($y - 1); $i++)
{
"`$(`$c$i)"
}
$code += '"' + ($res -join '') + '"'
$code += "}" * $y
$code = $code -join "`n"
iex $($code) | sc test.txt
# 600000 записей
Обычная запись, через set-content выдаёт:
0 139 > measure-command { .\2 }
Days : 0
Hours : 0
Minutes : 0
Seconds : 10
Milliseconds : 853
Ticks : 108537147
TotalDays : 0,000125621697916667
TotalHours : 0,00301492075
TotalMinutes : 0,180895245
TotalSeconds : 10,8537147
TotalMilliseconds : 10853,7147
Наверное со стримрайтером будет быстрее.
# 600000 записей »
Количество комбинаций не может быть 600 000 для "по 6 из 10". (код для проверки (http://forum.oszone.net/post-2920945-18.html))
Ошибка в первом for:
[array] $code = "for (`$c0 = 0; `$c0 -le $($y - 1); `$c0++) {" »$($y - 1) нужно заменить на $($x.count-1).
Кстати, что бы не писать все время -1, можно исользовать -lt:
for ($c0 = 0; $c0 -lt $x.count; $c0++)
Теперь получится верное количество. На моем олд пк результат 43 сек.
Foreigner
15-05-2020, 09:03
Fors1k_m,
Вы код поправьте.
C:\Users\user\Desktop\3.ps1:16 знак:22
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~
Отсутствует '')'' в списке параметров функции.
C:\Users\user\Desktop\3.ps1:16 знак:24
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~~~~~~~~~~~
Непредвиденная лексема "$b$c$d$e$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:16 знак:26
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~~~~~~~~~
Непредвиденная лексема "$c$d$e$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:16 знак:28
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~~~~~~~
Непредвиденная лексема "$d$e$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:16 знак:30
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~~~~~
Непредвиденная лексема "$e$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:16 знак:32
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~~~
Непредвиденная лексема "$f");$i++
}}}}}}$file.Close()
}).TotalSeconds
"Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:16 знак:34
+ $file.Writeline("$a$b$c$d$e$f");$i++
+ ~~~~~~~
Непредвиденная лексема "");$i++
}}}}}}$file.Close()
}).TotalSeconds
"" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:20 знак:2
+ "Комбинаций: $i"
+ ~~~~~~~~~~~
Непредвиденная лексема "Комбинаций:" в выражении или операторе.
C:\Users\user\Desktop\3.ps1:20 знак:16
+ "Комбинаций: $i"
+ ~
В строке отсутствует завершающий символ: ".
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList
0 144 >
Вы код поправьте.
Выдает ворох ошибок: »Скопировал код прямо из поста. Запуск кода (https://yadi.sk/i/aZ-Lcwe00QAq1g)
У megaloman тоже работает:
Ваш код делается 13' ...»
Возможно, у вас что-то потерялось при копировании кода, попробуйте еще раз.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.