# Simple PIN - Algorithm Exercise

## Recommended Posts

I was reading an FAQ article about Microsoft's Hello 4 Business and there was a question about if H4B prevents the usage of simple PINs.

They described the method they used to evaluate the delta between the PIN digit values to prevent constant deltas.  I thought the "problem" was interesting and sought out to code an algorithm to accomplish this.  It was a fun exercise in logic.  I tried to make it a efficient as I could think of and designed it to support PINs of variable lengths (>= 4) and thought I'd share what I came up with.  I am interested if anyone has any thoughts on performance or efficiency improvements.

```;Inspiring Article - https://docs.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-faq#does-windows-hello-for-business-prevent-the-use-of-simple-pins

#include <StringConstants.au3>
#include <Array.au3>

Func _PINDeltas(ByRef \$sPIN)
;Quick Error check to Ensure PIN is Numeric Only
If Not StringIsDigit(\$sPIN) Then Return SetError(1, 0, -1)

;Quck Error Check to Verify PIN is at least four digits
If StringLen(\$sPIN) <= 3 Then Return SetError(2, 0, -1)

;Setup PIN values Array and Delta values Array
Local \$aPIN = StringSplit(\$sPIN,"",\$STR_NOCOUNT)

;Setup Variables for Delta algorithm: Delta array index tracker, Current PIN value and Delta value tracker
Local \$iDeltaIndex = 0
Local \$iPINValue = \$aPIN[\$iDeltaIndex]
Local \$iDeltaCounter = 0

;Delta Algorithm
Do
;If Current PIN position value + Delta > next PIN value, overflow to zero
If \$iPINValue + \$iDeltaCounter > \$aPIN[\$iDeltaIndex + 1] Then \$iPINValue -= 10
;If Current PIN position value + Delta = next PIN value, save Delta value and move to next PIN position
If \$iPINValue + \$iDeltaCounter = \$aPIN[\$iDeltaIndex + 1] Then
;Save Delta value
;Reset Delta value
\$iDeltaCounter = 0
;Increment Delta array index tracker
\$iDeltaIndex += 1
;Get next PIN value
\$iPINValue = \$aPIN[\$iDeltaIndex]
;Else increment Delta tracker value
Else
;Increment Delta value
\$iDeltaCounter += 1
EndIf
;Do until last Delta index is complete

;Return the Delta array
EndFunc

;If ArrayUnique returns a single index Delta array, then the PIN is simple
Return (UBound(_ArrayUnique(\$aDeltas,0,0,0,\$ARRAYUNIQUE_NOCOUNT))=1) ? 1 : 0
EndFunc

;Generate PIN list using the examples on the MS article
Local \$aPINs[]=["1111","1234","1357","9630","1593","7036","1231","1872"]
For \$sPIN in \$aPINs
_IsPINSimple(\$sPIN)
Next

ConsoleWrite(@CRLF)

;Generate 5 digit PINs
Local \$aPINs[]=["11111","12345","13579","96307","15937","70369","12312","18723"]
For \$sPIN in \$aPINs
_IsPINSimple(\$sPIN)
Next

Func _IsPINSimple(\$sPIN)
Local \$sDeltas = "(" & _ArrayToString(\$aDeltas,",") & ")"
Local \$sMsg = (_PINIsSimple(\$aDeltas)=1) ? "has a constant delta of " & \$sDeltas & ", so it is not allowed." : "does not have a constant delta " & \$sDeltas & ", so it is allowed."
ConsoleWrite("The PIN " & \$sPIN & " " & \$sMsg & @CRLF)
EndFunc```

Edited by spudw2k
Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

##### Share on other sites

Interesting algorithm which I should check out... but I have one pedantic detail that you can improve, use StringIsDigit instead of a regex for only checking if the string has digits ##### Share on other sites

Appreciate the feedback.  The difference is negligible, but the StringIsDigit function does seem to be faster.  Thanks.

Spoiler

Misc Code Snippets:
Projects: SubnetCalc
Cool Stuff:

## Create an account

Register a new account

• ### Recently Browsing   0 members

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...