% write a boolean function to get and validate a social insurance number.
% input in the form 999 999 999
% or 999-999-999
% function returns true if SIN is valid
function validateSIN (sinum : string) : boolean
var flagdigits, flagdigits_final : array 1 .. 4 of int
var flagdigits_string : array 1 .. 4 of string
var count, countTwo, finalCheck, whatRound, pos : int
var sinum2 : string
% valid numerical characters
const nonums := "1234567890"
count := 0
sinum2 := ""
%strip non numerical characters
% run this number of times there are characters in "sinum"
% store round number in "i"
for i : 1 .. length (sinum)
% check to see if sinum(i .. i) exists in nonums and store the position # in
% pos
pos := index (nonums, sinum (i .. i))
% if it exists, pos will be > 0
if pos > 0 then
% it exists, so add sinum(i..i) to sinum2, our string of only numbers
sinum2 := sinum2 + sinum (i .. i)
end if
end for
% initialize variables
for i : 1 .. 4
flagdigits_string (i) := ""
flagdigits_final (i) := 0
flagdigits (i) := 0
end for
% add to flagged the flagged digits
% we run this 4 times, counting by 2, starting at 2, ending at 8
for i : 2 .. 8 by 2
% we need a second counter in here that goes 1-4
count := count + 1
% we add into flagdigits slot count the integer at sinum2 (i .. i)
% str->int is necessary because we will be doing math ops on flagdigits
flagdigits (count) := strint (sinum2 (i .. i))
end for
% multiply flagged digits by 2, convert them to string and set them in
% flagdigits_string
for i : 1 .. 4
% multiply the number in flagdigits(i) by 2, convert the int to string
% stash it in flagdigits_string at slot i
flagdigits_string (i) := intstr (flagdigits (i) * 2)
end for
% add first and second digits of numbers that became two digits or more in
% size together
for i : 1 .. 4
% if flagdigits at slot i is > than 9, it is two digits long and needs to
% be compressed
if flagdigits (i) > 9 then
% run it twice, once for each digit... it won't be 3 digits
for r : 1 .. 2
% flagdigits_final(i) is equal to flagdigits_final(i) + str->int
% of flagdigits_string at slot (i) at place (r..r)
flagdigits_final (i) := flagdigits_final (i) + strint (flagdigits_string (i) (r .. r))
end for
end if
end for
% add together the SIN original numbers and the new flagged numbers from
% flagdigits_final, skipping the appropriate numbers
% set this up, needs to start at 0, will be adding to it
finalCheck := 0
for i : 1 .. 9
% if we're not working with slots 2,4,6,8 then we're good to proceed
if not i = 2 or not i = 4 or not i = 6 or not i = 8 then
% finalCheck is equal to finalCheck + string->integer of sinum2 at place
% (i..i)
finalCheck := finalCheck + strint (sinum2 (i .. i))
% IF IT IS SLOT 2 OR 4 OR 6 OR 8...
else
% change what round we're on based on whether i is 2 or 4 or 6 or 8
% cuz flagdigits_final has slots 1-4
case i of
label 2 :
whatRound := 1
label 4 :
whatRound := 2
label 6 :
whatRound := 3
label 8 :
whatRound := 4
end case
% add to finalcheck the correct number fron flagdigits_final at
% slot whatRound
finalCheck := finalCheck + flagdigits_final (whatRound)
end if
end for
% check if the final number is a multiple of 10 and return valid or
% otherwise
% start this off at 10, lowest multiple of 10
countTwo := 10
% some debugging stuff
put "finalcheck: ", finalCheck
% loop this and exit when we have a valid SIN (multiple of 10) or countTwo = 100
loop
exit when countTwo = finalCheck or countTwo = 100
% increase by 10 since we haven't exited
countTwo := countTwo + 10
end loop
% if finalcheck ended up being equal to countwo we have a valid sin (woo)
if finalCheck = countTwo then
result true
% otherwise we hit the roof and it wasn't valid. exit and return false
elsif countTwo = 100 then
result false
end if
end validateSIN
% test
var SIN : string
put "SIN: " ..
get SIN : *
% call function and run it on SIN
if validateSIN (SIN) then
put "*** VALID ***"
else
put "*** INVALID ***"
end if