密码生成器cmd批处理

时间:2016-01-14 23:58:46

标签: windows batch-file cmd

我尝试使用批处理创建一个简单的密码生成器 我知道如果我尝试使用真正的语言会更容易,但我需要在cmd批处理中使用它 我需要它生成一个10位数的密码,包括最少1个小写字母1个大写字母1个数字和一个特殊字符。

我找到了这个代码 但正如你所看到的,它并不能确保我的所有限制都适用

@Echo Off
cd %~dp0
Setlocal EnableDelayedExpansion
Set _RNDLength=10
Set _Alphanumeric=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%
Set _Str=%_Alphanumeric%9876543210
echo %_Str:~18%
:_LenLoop
IF NOT "%_Str:~18%"=="" SET _Str=%_Str:~9%& SET /A _Len+=9& GOTO :_LenLoop
SET _tmp=%_Str:~9,1%
SET /A _Len=_Len+_tmp
Set _count=0
SET _RndAlphaNum=
:_loop
Set /a _count+=1
SET _RND=%Random%
Set /A _RND=_RND%%%_Len%
SET _RndAlphaNum=!_RndAlphaNum!!_Alphanumeric:~%_RND%,1!
If !_count! lss %_RNDLength% goto _loop
echo !_RndAlphaNum!

2 个答案:

答案 0 :(得分:3)

这个问题有一个固有的复杂问题:每个必需子集(大写,小写,数字和特殊)的字符集具有不同的频率,因此不太可能出现特殊字符,更可能出现字母。但是,即使频率均衡(重复特殊字符和数字直到所有四个子集具有相同的字符数),这并不能保证所有四个集合至少出现一次。

下面的解决方案使用不同的方法:它分别管理每个子集,并创建一个包含每个子集的10个数字的列表。这样,就可以计算每个子集在列表中出现的次数,并轻松强制所需的条件。

@echo off

setlocal
set "set[1]=ABCDEFGHIJKLMNOPQRSTUVWXYZ"  &  set "len[1]=26"  &  set "num[1]=0"
set "set[2]=abcdefghijklmnopqrstuvwxyz"  &  set "len[2]=26"  &  set "num[2]=0"
set "set[3]=0123456789"                  &  set "len[3]=10"  &  set "num[3]=0"
set "set[4]=~!@#$%%"                     &  set "len[4]=6"   &  set "num[4]=0"
setlocal EnableDelayedExpansion

rem Create a list of 10 random numbers between 1 and 4;
rem the condition is that it must be at least one digit of each one

rem Initialize the list with 10 numbers
set "list="
for /L %%i in (1,1,10) do (
   set /A rnd=!random! %% 4 + 1
   set "list=!list!!rnd! "
   set /A num[!rnd!]+=1
)

:checkList
rem Check that all digits appear in the list at least one time
set /A mul=num[1]*num[2]*num[3]*num[4]
if %mul% neq 0 goto listOK

   rem Change elements in the list until fulfill the condition

   rem Remove first element from list
   set /A num[%list:~0,1%]-=1
   set "list=%list:~2%"

   rem Insert new element at end of list
   set /A rnd=%random% %% 4 + 1
   set "list=%list%%rnd% "
   set /A num[%rnd%]+=1

goto checkList
:listOK

rem Generate the password with the sets indicated by the numbers in the list
set "RndAlphaNum="
for %%a in (%list%) do (
   set /A rnd=!random! %% len[%%a]
   for %%r in (!rnd!) do set "RndAlphaNum=!RndAlphaNum!!set[%%a]:~%%r,1!"
)

echo !RndAlphaNum!

可以很容易地修改此代码,以便从每个子集生成具有给定数量元素的10个字符的密码;要做到这一点,只需使用所需的数字初始化“num”数组(必须总和10),每次在列表中插入新元素时减少这些数字并更改<所有元素的em> sum 为零。

答案 1 :(得分:1)

如果插入此逻辑

SET _restrict=
FOR /F "delims=" %%a IN ('CALL ECHO !_RndAlphaNum! ^| findstr /R /C:"[A-Z]" ^| findstr /R /C:"[a-z]" ^| findstr /R /C:"[~!@#$%]"') DO (
   SET _restrict=%%a
)
IF "!_restrict!"=="" GOTO _loop

之后

If !_count! lss %_RNDLength% goto _loop

它将强制密码生成继续,直到满足您的3个条件(至少1个上限,至少1个下限和至少1个特殊字符,我假设它们仅限于_Alphanumeric中定义的那些)。

注意:这可能会导致生成一个长度超过10个字符的字符串。如果需要,你可以做一些事情来截断字符串,但是因为10是最小的...为什么不让它变得疯狂?