Forum Discussion

Mike_Finney_119's avatar
Mike_Finney_119
Icon for Nimbostratus rankNimbostratus
Sep 06, 2013

iRule regex to normalize phone numbers?

Been searching but no luck so far looking for a iRule with a regex or some other method to normalize phone numbers from AD for use to pass to an SMS gateway. I have adapted the method here: https://devcentral.f5.com/articles/one-time-passwords-via-an-sms-gateway-with-big-ip-access-policy-manager.UioetD99-jy for our local Multitech SMS gateway and it does work fine with "unformatted" phone numbers like xxxxxxxxxxx, but management is not keen on my changing everyone's mobile number to exclude those characters for readability. Basically, our AD has a mismatch of methods for phone numbers, some have dashes, some have spaces, some have parentheses around the area code, the EU numbers have dots instead of dashes, so xxx.xxx.xxxx. Has anyone tried this before? Any suggestions would be most welcomed as my iRule and regex -fu is not as strong as it should be. :)

 

16 Replies

  • OK, two steps got it to work.

     

    Code
    when  ACCESS_POLICY_AGENT_EVENT {
           expr srand([clock clicks])
           set otp [string range [format "%08d" [expr int(rand() * 1e9)]] 1 6 ]
           set mail [ACCESS::session data get "session.ldap.last.attr.mail"]
           set mobile [ACCESS::session data get "session.ldap.last.attr.mobile"]
           set mobile2 [string map {"." "" " " "" "-" "" "(" "" ")" "" "+" ""} $mobile]
           ACCESS::session data set session.user.otp.pw $otp
           ACCESS::session data set session.user.otp.mobile $mobile2
           ACCESS::session data set session.user.otp.username [ACCESS::session data get "session.logon.last.username"]
    }
  • Hi Kevin,

     

    That worked as well, thanks for throwing that out there as it makes me realize the order can make a big difference there.

     

  • Hi Jason, I was thinking about it once I got home looking in my closet, and I would like to ask if Kevin could get the shirt as he was a real highlight on how helpful the community can be. Thanks!
  • One more thing. Because you originally asked about a regex function:

    % set num1 "1234567890"
    % set num2 "123-456-7890"
    % set num3 "123.456.7890"
    % set num4 "123 456 7890"
    % set num5 "(123) 456-7890"
    % set num6 "123foo456bar7890"
    
    % time { regsub -all {\D} $num1 "" newval; puts $newval }
    1234567890
    26 microseconds per iteration
    
    % time { regsub -all {\D} $num2 "" newval; puts $newval }
    1234567890
    29 microseconds per iteration
    
    % time { regsub -all {\D} $num3 "" newval; puts $newval }
    1234567890
    31 microseconds per iteration
    
    % time { regsub -all {\D} $num4 "" newval; puts $newval }
    1234567890
    37 microseconds per iteration
    
    % time { regsub -all {\D} $num5 "" newval; puts $newval }
    1234567890
    32 microseconds per iteration
    
    % time { regsub -all {\D} $num6 "" newval; puts $newval }
    1234567890
    35 microseconds per iteration
    
    % time { puts [string map {"." "" " " "" "-" "" "(" "" ")" "" "+" ""} $num3] }
    1234567890
    45 microseconds per iteration
    

    The "\D" regex option used in regsub will replace ANY non-numeric character (see num6), so it'll technically do a better job, and is more flexible than the string map version.

  • You can see the penalty you pay for using regex. If stripping all non-numeric is the goal, better off with the proc.

     

  • Indeed:

    % set num1 "123-456-7890"
    
    % time { regsub -all {\D} $num1 "" } 10000
    3.172 microseconds per iteration
    
    % time { string map {"." "" " " "" "-" "" "(" "" ")" ""} $num1 } 10000
    1.1674 microseconds per iteration
    

    So then it's really a trade-off between speed and flexibility. Regex will catch more anomalies (ie. "123foo456bar7890") at the expense of CPU time. That said, the goal here was convert a string during access policy evaluation, which should only happen once per session.