Forum Discussion

Rory_Hewitt_139's avatar
Rory_Hewitt_139
Icon for Nimbostratus rankNimbostratus
Jun 04, 2014

Determining processing based on flags in a URL

I have a URL which will come in as

 

/features?features=10010001

 

where each '1' or '0' is a 'flag'. I need to check each flag in turn and depending on its value, XOR it with a matching flag stored as a preset in my iRule, and eventually return the result. The presets will be stored as variables called e.g. 'flag1', 'flag2' etc. So my processing would be to split the '10--01-00---01' string into an array of flags, process each element in the array, match it with the related preset variable, do the XOR and then return the XOR'ed string as a 200 response.

 

As a start, I'm trying to figure out the best way to convert the '10--01-00---01' string into an array of flags that I can process.

 

I hope the above makes sense.

 

  • that kinda works, except that the characters could potentially be 0, 1 or -

    may we remove - before scanning?

    % scan [string map {"-" ""} 10--01-00---01] %2d%2d%2d%2d a b c d
    4
    
    % put "$a $b $c $d"
    10 1 0 1
    

    by the way, if flag is only one digit each, can we use split?

    % split [string map {"-" ""} 10--01-00---01] {}
    1 0 0 1 0 0 0 1
    
  • what about scan or regexp?

     scan
    
    % scan 10010001 %2d%2d%2d%2d a b c d
    4
    
    % put "$a $b $c $d"
    10 1 0 1
    
    % time "scan 10010001 %2d%2d%2d%2d a b c d" 1000
    5.319 microseconds per iteration
    
     regexp
    
    % regexp {(\d\d)(\d\d)(\d\d)(\d\d)} 10010001 m a b c d
    1
    
    % put "$a $b $c $d"
    10 01 00 01
    
    % time "regexp {(\d\d)(\d\d)(\d\d)(\d\d)} 10010001 m a b c d" 1000
    3.077 microseconds per iteration
    
    • Rory_Hewitt_139's avatar
      Rory_Hewitt_139
      Icon for Nimbostratus rankNimbostratus
      Hey @nitass, that kinda works, except that the characters could potentially be 0, 1 or -, so I can't use %d in scan or \d in regex. I can use %c in scan, but it converts them to a Unicode integer. So for instance, scan $flags %c%c%c%c%c%c%c%c flag1 flag2 flag3 flag4 flag5 flag6 flag7 flag8 gives me "49 45 48 45 45 45 45 49". Any way to simply chop them out as single characters?
    • JG's avatar
      JG
      Icon for Cumulonimbus rankCumulonimbus
      The test results here seem to go contrary to the prevalent view that prefers "scan" to "regexp" for performance.
  • what about scan or regexp?

     scan
    
    % scan 10010001 %2d%2d%2d%2d a b c d
    4
    
    % put "$a $b $c $d"
    10 1 0 1
    
    % time "scan 10010001 %2d%2d%2d%2d a b c d" 1000
    5.319 microseconds per iteration
    
     regexp
    
    % regexp {(\d\d)(\d\d)(\d\d)(\d\d)} 10010001 m a b c d
    1
    
    % put "$a $b $c $d"
    10 01 00 01
    
    % time "regexp {(\d\d)(\d\d)(\d\d)(\d\d)} 10010001 m a b c d" 1000
    3.077 microseconds per iteration
    
    • Rory_Hewitt_139's avatar
      Rory_Hewitt_139
      Icon for Nimbostratus rankNimbostratus
      Hey @nitass, that kinda works, except that the characters could potentially be 0, 1 or -, so I can't use %d in scan or \d in regex. I can use %c in scan, but it converts them to a Unicode integer. So for instance, scan $flags %c%c%c%c%c%c%c%c flag1 flag2 flag3 flag4 flag5 flag6 flag7 flag8 gives me "49 45 48 45 45 45 45 49". Any way to simply chop them out as single characters?
    • JG's avatar
      JG
      Icon for Cumulonimbus rankCumulonimbus
      The test results here seem to go contrary to the prevalent view that prefers "scan" to "regexp" for performance.
  • that kinda works, except that the characters could potentially be 0, 1 or -

    may we remove - before scanning?

    % scan [string map {"-" ""} 10--01-00---01] %2d%2d%2d%2d a b c d
    4
    
    % put "$a $b $c $d"
    10 1 0 1
    

    by the way, if flag is only one digit each, can we use split?

    % split [string map {"-" ""} 10--01-00---01] {}
    1 0 0 1 0 0 0 1
    
    • Rory_Hewitt_139's avatar
      Rory_Hewitt_139
      Icon for Nimbostratus rankNimbostratus
      Nope, we need the '-' in there - it implies 'null'. Although, of course, split would work fine -I don't know why I didn't think of it - probably because I'm not a Tcl programmer :) In any event, I have this working - using substr: for {set x 0} {$x < 8} {incr x} { set flag [string index $flags $x] switch $flag { "0" {...} "1" {...} default {...} } which seems to do the job rather nicely. Thanks for the help!
  • that kinda works, except that the characters could potentially be 0, 1 or -

    may we remove - before scanning?

    % scan [string map {"-" ""} 10--01-00---01] %2d%2d%2d%2d a b c d
    4
    
    % put "$a $b $c $d"
    10 1 0 1
    

    by the way, if flag is only one digit each, can we use split?

    % split [string map {"-" ""} 10--01-00---01] {}
    1 0 0 1 0 0 0 1
    
    • Rory_Hewitt_139's avatar
      Rory_Hewitt_139
      Icon for Nimbostratus rankNimbostratus
      Nope, we need the '-' in there - it implies 'null'. Although, of course, split would work fine -I don't know why I didn't think of it - probably because I'm not a Tcl programmer :) In any event, I have this working - using substr: for {set x 0} {$x < 8} {incr x} { set flag [string index $flags $x] switch $flag { "0" {...} "1" {...} default {...} } which seems to do the job rather nicely. Thanks for the help!