cmd 批处理中的密码生成器
Password generator in cmd batch
我正在尝试使用批处理创建一个简单的密码生成器。我知道如果我尝试使用真正的语言会容易得多,但我需要它在 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!
如果你插入这个逻辑
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 是最小值...为什么不让它变得疯狂?
这个问题有一个内在的复杂性:字符集对于每个所需的子集(大写、小写、数字和特殊字符)都有不同的频率,因此出现特殊字符的可能性较小,而出现特殊字符的可能性更大一封信。但是,即使频率相等(重复特殊字符和数字直到所有四个子集具有相同数量的字符),这也不能保证所有四个集合至少出现一次。
下面的解决方案使用了一种不同的方法:它分别管理每个子集并创建一个包含 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),每次在列表中插入新元素并更改时递减这些数字所有元素的 sum 为零的条件。
我正在尝试使用批处理创建一个简单的密码生成器。我知道如果我尝试使用真正的语言会容易得多,但我需要它在 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!
如果你插入这个逻辑
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 是最小值...为什么不让它变得疯狂?
这个问题有一个内在的复杂性:字符集对于每个所需的子集(大写、小写、数字和特殊字符)都有不同的频率,因此出现特殊字符的可能性较小,而出现特殊字符的可能性更大一封信。但是,即使频率相等(重复特殊字符和数字直到所有四个子集具有相同数量的字符),这也不能保证所有四个集合至少出现一次。
下面的解决方案使用了一种不同的方法:它分别管理每个子集并创建一个包含 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),每次在列表中插入新元素并更改时递减这些数字所有元素的 sum 为零的条件。