All pastes #775421 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-11-15 16:20 UTC
rendered paste body
% 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