12-13-2023 08:14 AM
I need to calculate a simple hash from a string of characters (containing no whitespace). I can't figure out the regexp I need to use in the below "action foreach" statement to parse the string charcter by character:
event manager applet test1
event none
action 0100 set range "gig1/0/1-2"
action 0110 set csum "0"
action 0120 foreach char "$range" "\C"
action 0130 add $csum $char
action 0140 set csum "$_result"
action 0150 end
action 0160 divide $csum 255
action 0170 set csum "$_remainder"
action 0180 puts "CSUM = $csum"
Any ideas?
Solved! Go to Solution.
12-13-2023 02:55 PM - edited 12-14-2023 07:13 AM
Far too much fun. Might as well be programming in assembly language. Not that there's anything wrong with that.
event manager environment CHARMAP , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > \077 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z
event manager applet test4
event none
action 100 set range "gig1/0/1-2"
action 110 set csum1 "0"
action 120 set csum2 "0"
action 130 set checksum "0"
action 140 set index "0"
action 150 set char ""
action 160 set map_char ""
action 170 string length "$range"
action 180 set length "$_string_result"
action 190 while $index lt $length
action 200 regexp "^." "$range" char
action 210 puts "$char"
action 220 set index1 "44"
action 230 foreach map_char "$CHARMAP" " "
action 240 if $char eq "$map_char"
action 250 increment csum1 $index1
action 260 divide $csum1 255
action 270 set csum1 "$_remainder"
action 280 increment csum2 $csum1
action 290 divide $csum2 255
action 300 set csum2 "$_remainder"
action 310 break
action 320 end
action 330 increment index1 1
action 340 end
action 350 string trimleft "$range" "$char"
action 360 set range "$_string_result"
action 370 increment index 1
action 380 end
action 390 increment checksum $csum2
action 400 multiply $checksum 256
action 410 set checksum $_result
action 420 increment checksum $csum1
action 430 puts "Checksum = $checksum"
12-13-2023 08:22 AM
hello @6502
The "foreach" construct is not directly designed to iterate over characters in a string. Instead, it is primarily used to iterate over elements in a list. However, you can achieve your goal by using a combination of other actions.
event manager applet test1
event none
action 0100 set range "gig1/0/1-2"
action 0110 set csum 0
# Loop through each character in the string
action 0120 for each i in "$range" {
action 0130 set char [string index "$range" $i]
# Convert the character to ASCII and add it to the checksum
action 0140 set ascii_val [scan $char "%c"]
action 0150 math add csum $ascii_val
action 0160 }
# Output the checksum
action 0170 puts "CSUM = $csum"
12-13-2023 09:52 AM
Foreach loop iterates over each word so the number of words and spaces is known. string length is sum of the string (all char and spaces) then arithmetic to subtract the spaces from string length.
event manager applet test
event none
action 010 set mystring "learning to count with eem 1 2 3"
action 014 set num "-1"
action 020 foreach word "$mystring"
action 030 add $num 1
action 035 set num "$_result"
action 040 end
action 100 string length "$mystring"
action 110 subtract $_string_result $_result
action 120 puts "$_result characters in mystring"
action 200 puts "$num spaces in mystring"
INET#event manager run test
25 characters in mystring
7 spaces in mystring
12-13-2023 10:05 AM
Thanks M02@rt37 for the algorithm, but unfortunately those string operators don't appear to exist in EEM, or at least in a way that i can use them with local applet variables. Here's what I came up with that could work, using "action regexp", if I could only figure out the right search string to use:
...
action 150 while $index lt $length
action 160 regexp "/^.{$index}[:word:]/" "$range" char
action 180 puts "$char"
action 190 increment index 1
action 200 increment csum $char
action 210 end
The goal of the regexp search string is to return the single character within $range at position $index and assign it to $char.
12-13-2023 11:57 AM - edited 12-13-2023 11:58 AM
OK, figured out how to parse the string character by character:
event manager applet test4
event none
action 100 set range "gig1/0/1-2"
action 110 set csum "0"
action 120 set index "0"
action 130 set char ""
action 140 string length "$range"
action 150 set length "$_string_result"
action 160 while $index lt $length
action 170 regexp "^." "$range" char
action 180 puts "$char"
action 190 increment index 1
action 200 add $csum $char
action 201 set csum "_$result"
action 210 string trimleft "$range" "$char"
action 220 set range "$_string_result"
action 230 end
action 240 divide $csum 255
action 250 set csum "$_remainder"
action 260 puts "CSUM = $csum"
But as was aluded to earlier by M02@rt37 , the add action in line 200 fails becuase $char contains a alpha character instead of a number. Since there doesn't seem to be any typing in eem scripts, I was hoping that it would just force the alpha into a number , but sadlly no. Is there any way to easily convert the alpha into a number? It doesn't necessarily have to be the ASCII value. I guess I could use a loop similar to the above to iterate through a list of "abcde..xyz0123...9-/" and use the loop index when the match occurs as the "number", but this is already getting too ugly...
12-13-2023 01:05 PM
Are you looking for the ascii number for each character to perform the divide function and get the remainder? If so you will need EEM/TCL for this. Below is using the tcl shell for testing and can be written in EEM TCL if this meets your need.
INET#tclsh
INET(tcl)#set data "gig1/0/1-2"
gig1/0/1-2
INET(tcl)#set num 0
0
INET(tcl)#foreach char [split $data ""] {
+> set output [scan $char %c]
+> set sum [expr $output + $num]
+> puts $sum
+> set num $sum
+>}
103
208
311
360
407
455
502
551
596
646
INET(tcl)#set result [expr $num % 255]
136
12-13-2023 02:55 PM - edited 12-14-2023 07:13 AM
Far too much fun. Might as well be programming in assembly language. Not that there's anything wrong with that.
event manager environment CHARMAP , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > \077 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z
event manager applet test4
event none
action 100 set range "gig1/0/1-2"
action 110 set csum1 "0"
action 120 set csum2 "0"
action 130 set checksum "0"
action 140 set index "0"
action 150 set char ""
action 160 set map_char ""
action 170 string length "$range"
action 180 set length "$_string_result"
action 190 while $index lt $length
action 200 regexp "^." "$range" char
action 210 puts "$char"
action 220 set index1 "44"
action 230 foreach map_char "$CHARMAP" " "
action 240 if $char eq "$map_char"
action 250 increment csum1 $index1
action 260 divide $csum1 255
action 270 set csum1 "$_remainder"
action 280 increment csum2 $csum1
action 290 divide $csum2 255
action 300 set csum2 "$_remainder"
action 310 break
action 320 end
action 330 increment index1 1
action 340 end
action 350 string trimleft "$range" "$char"
action 360 set range "$_string_result"
action 370 increment index 1
action 380 end
action 390 increment checksum $csum2
action 400 multiply $checksum 256
action 410 set checksum $_result
action 420 increment checksum $csum1
action 430 puts "Checksum = $checksum"
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide