NSIS 使用正则表达式进行模式匹配。密码验证
NSIS using a regEx for pattern matching. Password validation
我一直在尝试将字符串与密码验证模式相匹配。例如密码必须包含 upper/lower 和特殊字符。
我已经使用 StrCSpn(修改为区分大小写)函数来扫描字符串中的字符,但我必须有一个单独的列表来存放特殊字符和 upper/lower 大小写字母。所以代码有点笨重
https://nsis.sourceforge.io/StrCSpn,_StrCSpnReverse:_Scan_strings_for_characters
有没有像这里这样在 NSIS 中使用正则表达式的方法
您可以使用 NSISpcre plug-in:
Function PasswordMatchesPolicy
Push [=10=]
Push
Push
Push 0
Push 0
Exch 5
Push `^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*)$$` #whosebug.com/questions/43127814/regex-for-at-least-1-number-1-lower-case-and-1-upper-case-letter
NSISpcre::REMatches
Pop [=10=]
${If} [=10=] == true
Pop [=10=]
${For} 1 [=10=]
Pop
${Next}
Push 1
${Else}
Push ""
${EndIf}
Exch 3
Pop
Pop
Pop [=10=]
FunctionEnd
!include LogicLib.nsh
ShowInstDetails show
Section
!macro Test str
Push "${str}"
Call PasswordMatchesPolicy
Pop [=10=]
${If} [=10=] <> 0
StrCpy [=10=] PASS
${Else}
StrCpy [=10=] FAIL
${EndIf}
DetailPrint "[=10=]:${str}"
!macroend
!insertmacro Test "foo"
!insertmacro Test "Foo"
!insertmacro Test "Foo1"
!insertmacro Test "Foo#"
!insertmacro Test "Foo1#"
SectionEnd
或者如果您只关心 ASCII:
Function PasswordMatchesPolicy
!define /IfNDef C1_UPPER 0x0001
!define /IfNDef C1_LOWER 0x0002
!define /IfNDef C1_DIGIT 0x0004
!define /IfNDef C1_DEFINED 0x0200
System::Store S
System::Call 'KERNEL32::lstrcpyA(@r1,ms)'
StrCpy ""
StrCpy 0
loop:
System::Call '*(&i,&i1.r4)'
${If} <> 0
${If} >= 65
${AndIf} <= 90
IntOp | ${C1_UPPER}
${ElseIf} >= 97
${AndIf} <= 122
IntOp | ${C1_LOWER}
${ElseIf} >= 48
${AndIf} <= 57
IntOp | ${C1_DIGIT}
${Else}
IntOp | ${C1_DEFINED} ; Just mark it as "something"
${EndIf}
IntOp + 1
Goto loop
${EndIf}
IntOp & 3
${If} = 3 ; C1_UPPER and C1_LOWER
${AndIf} >= 4 ; Digit or symbol
Push 1
${Else}
Push 0
${EndIf}
System::Store L
FunctionEnd
我一直在尝试将字符串与密码验证模式相匹配。例如密码必须包含 upper/lower 和特殊字符。
我已经使用 StrCSpn(修改为区分大小写)函数来扫描字符串中的字符,但我必须有一个单独的列表来存放特殊字符和 upper/lower 大小写字母。所以代码有点笨重 https://nsis.sourceforge.io/StrCSpn,_StrCSpnReverse:_Scan_strings_for_characters
有没有像这里这样在 NSIS 中使用正则表达式的方法
您可以使用 NSISpcre plug-in:
Function PasswordMatchesPolicy
Push [=10=]
Push
Push
Push 0
Push 0
Exch 5
Push `^(?:(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*)$$` #whosebug.com/questions/43127814/regex-for-at-least-1-number-1-lower-case-and-1-upper-case-letter
NSISpcre::REMatches
Pop [=10=]
${If} [=10=] == true
Pop [=10=]
${For} 1 [=10=]
Pop
${Next}
Push 1
${Else}
Push ""
${EndIf}
Exch 3
Pop
Pop
Pop [=10=]
FunctionEnd
!include LogicLib.nsh
ShowInstDetails show
Section
!macro Test str
Push "${str}"
Call PasswordMatchesPolicy
Pop [=10=]
${If} [=10=] <> 0
StrCpy [=10=] PASS
${Else}
StrCpy [=10=] FAIL
${EndIf}
DetailPrint "[=10=]:${str}"
!macroend
!insertmacro Test "foo"
!insertmacro Test "Foo"
!insertmacro Test "Foo1"
!insertmacro Test "Foo#"
!insertmacro Test "Foo1#"
SectionEnd
或者如果您只关心 ASCII:
Function PasswordMatchesPolicy
!define /IfNDef C1_UPPER 0x0001
!define /IfNDef C1_LOWER 0x0002
!define /IfNDef C1_DIGIT 0x0004
!define /IfNDef C1_DEFINED 0x0200
System::Store S
System::Call 'KERNEL32::lstrcpyA(@r1,ms)'
StrCpy ""
StrCpy 0
loop:
System::Call '*(&i,&i1.r4)'
${If} <> 0
${If} >= 65
${AndIf} <= 90
IntOp | ${C1_UPPER}
${ElseIf} >= 97
${AndIf} <= 122
IntOp | ${C1_LOWER}
${ElseIf} >= 48
${AndIf} <= 57
IntOp | ${C1_DIGIT}
${Else}
IntOp | ${C1_DEFINED} ; Just mark it as "something"
${EndIf}
IntOp + 1
Goto loop
${EndIf}
IntOp & 3
${If} = 3 ; C1_UPPER and C1_LOWER
${AndIf} >= 4 ; Digit or symbol
Push 1
${Else}
Push 0
${EndIf}
System::Store L
FunctionEnd