Jump to content
Sign in to follow this  

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)
    Local $aDeltas[UBound($aPIN)-1]

    ;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
        ;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
            $aDeltas[$iDeltaIndex] = $iDeltaCounter
            ;Reset Delta value
            $iDeltaCounter = 0
            ;Increment Delta array index tracker
            $iDeltaIndex += 1
            ;Get next PIN value
            $iPINValue = $aPIN[$iDeltaIndex]
        ;Else increment Delta tracker value
            ;Increment Delta value
            $iDeltaCounter += 1
    ;Do until last Delta index is complete
    Until $iDeltaIndex > UBound($aDeltas)-1

    ;Return the Delta array
    Return $aDeltas

Func _PINIsSimple(ByRef $aDeltas)
    ;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

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


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

Func _IsPINSimple($sPIN)
    Local $aDeltas = _PINDeltas($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)


Edited by spudw2k

Share this post

Link to post
Share on other sites

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...