Hi,
I have requirement to validate 4-digit pin. Below are the requirement of the 4-digit number
1. pin should not allow sequential numbers
2. pin should not allow same numbers
example: 1234 or 4321 or 0000, 1111 or 4444 or 2222 or 3333 numbers are not allowed as a card pin.
can anyone please help me how to write logic for the validation.
thanks in advance!
Discussion posts and replies are publicly visible
A first idea here. Not sure if it catches all edge cases.
a!localVariables( local!pins: {"7369", "1234", "4321", "0000", "1111", "4444", "2222", "3333"}, a!forEach( items: local!pins, expression: and( fv!item <> concat(tointeger(left(fv!item, 1)) + enumerate(4)), /* positive sequence */ fv!item <> concat(tointeger(left(fv!item, 1)) + enumerate(4) * -1), /* negative sequence */ fv!item <> rept(mid(fv!item, 1, 1), 4), /* 4 times the first character */ fv!item <> rept(mid(fv!item, 2, 1), 4), /* 4 times the second character */ fv!item <> rept(mid(fv!item, 3, 1), 4), /* 4 times the third character */ fv!item <> rept(mid(fv!item, 4, 1), 4) /* 4 times the fourth character */ ) ) )
Hi Druva,
Please try the below code. Here rule input (ri!pin) is of type text
if( and( len(ri!pin)=4, len(tostring(tointeger(ri!pin)))=len(ri!pin) ), a!localVariables( local!numbersUsed:{ int(charat(ri!pin,1)), int(charat(ri!pin,2)), int(charat(ri!pin,3)), int(charat(ri!pin,4)) }, if( length(union(local!numbersUsed,local!numbersUsed))<>length(local!numbersUsed), "numbers cannot be repeated in pin", if( and( local!numbersUsed[1]+1=local!numbersUsed[2], local!numbersUsed[2]+1=local!numbersUsed[3], local!numbersUsed[3]+1=local!numbersUsed[4], ), "cannot be sequentail numbers", "no error" ) ) ), "pin should be 4 characters and should contain only numbers" )
a!localVariables(local!a:regexmatch( pattern:"^(?!.*?(?:012|123|234|345|456|567|678|789|987|876|765|654|543|432|321|210|(\d)\1\1))\d{4}$", searchString:9989, regexFlags:"gms"),local!a)
Hi , can you check the above code by placing in expression rule working fine for me .if you don't find regexmatch() in your rule , then add "Regular expression functions" plugin
Hi, Here is a solution which covers all edge cases. (Some humble bragging)The expression rule 'isPinValid' provides an array as a result. The first item in the result is a Boolean indicating if the Pin is valid, the second item in the result is the validation message
a!localVariables( /* Checks if the pin is compliant to the rules: has 4 digits, no sequences (ascending or descending) and not the same 4 digits */ /* Get the digits of the pin - ri!pin is in text format */ local!allDigits: tostring(ri!pin), local!count: len(local!allDigits), local!digits: a!forEach(items: enumerate(local!count),expression: tointeger(local!allDigits[fv!index])), /* Prep for the sequence test, calculating the difference between the digits - ldrop is for the edge case if the pin starts with a 1 */ local!seq:ldrop({0,local!digits} - {local!digits,0},1), /* Same digits? */ local!sd: if(1=length(union(local!digits,local!digits)),true,false), /* Check if we have a sequence of numbers e. g. 2345 or 8765 */ local!seq1: if(3<=length(wherecontains(-1,local!seq)),true,false), local!seq2: if(3<=length(wherecontains(1,local!seq)),true,false), /* Is the pin valid (true), or is one of the rules violated? (false) */ local!check: not(or(4<>local!count,local!sd,local!seq1,local!seq2)), { local!check, /* Providing the confirmation and/or error message */ a!match(value:true, whenTrue: count(local!digits)<>length(local!digits), then: "Pin can only contain Digits", whenTrue: local!check, then: "Pin is valid", whentrue:4<>local!count, then: "Pin has not 4 digits", whentrue: local!sd, then: "Pin can't have the same 4 digits", whenTrue: or(local!seq1,local!seq2), then: "Pin can't have digits in " & if(local!seq1,"a","de") & "cending sequence", default: "Not a valid pin" ) } )