hexHunt

hexHunt is a procedure that will collectively hunt line by line for the start of and end of an specific tag, using hexadecimal character pattern searching.

In this example we are checking the conditions that % is the first character, and that _ is next in sequence, that _ is second to last, and % is the last. In which if so, concludes we have a correctly formatted tag. Collect and store and do whatever with like execute an word to tag swap mechanism.

This works well in template systems where you need to replace a placeholder tag with actual data from a source. You would populate a document with an placeholder like: %_title_% which would be replaced with the site title "hexHunt Example".

Example:

Using the string of: This is an example of <b>%_hex_hunt_%</b>

hex string: 5468697320697320616e206578616d706c65206f66203c623e255f6865785f68756e745f253c2f623e

Returns the tag %_hex_hunt_%

The tags can be defined within the procedure checkTag where % and _ are represented by their hex values

proc checkTag { args } {
    set tag      [lindex $args 0] ;# What we are looking for
    set hexBlock [lindex $args 1] ;# our hexBlock [a2 b3 d4]

    # switch $tag
    #   This checks to see if the tag provided exists within the block given
    # Cases:
    # Tag   # Description                                                 # Result
    #   % | Activate a switch on our hexChar to see if it contains "25" | returns value: 1
    #   _ | Activate a switch on our hexChar to see if it contains "5f" | returns value: 1
    switch $tag {
        "%" { switch $hexBlock { 25 { return 1 } } }
        "_" { switch $hexBlock { 5f { return 1 } } }
    } ;# end switch
} ;# end proc

proc hexHunt { args } {

    set range ""
    set tagKeys ""
    set za 0 ;# This is used as our list index

    # x = index of cursor 1 at first index
    # y = index of cursor 2 at second index
    # z = string length count

    set lines [binary encode hex "This is an example of <b>%_hex_hunt_%</b>"]

    foreach line $lines {
        set list ""
        set string_length [string length $line]

        for { lassign {0 1 0} x y z } {$z < $string_length} {incr z} {
            ##
            lappend list [string range $line $x $y] ;# append our two characters of our hexString
            incr x 2 ; incr y 2                     ;# Increase both of our cursors by two
            switch [string range $line $x $y] { "" { break } } ;# if we than reach the end of our string characters break
                                                                # we do this because our string length is not our character length
            ##
        } ;# end for

        foreach item $list {
        #   puts "is my item a % at index $za | [binary decode hex $item] | $item"
            set hexBlock $item ;# Get our two characters from our hex string

            # switch checkTag "%"
            #   This checks to see if the tag provided exists within the block given
            # Cases:
            #   1       | We have a valid tag, increase our block to the next element, and check if the next element matches _
            #   default | We have a valid tag, decrease our block to the previous element and check if the previous block matches _
            switch [checkTag "%" $hexBlock] {
                1 {
        #           puts "yes! at index $za"
        #           puts "Is my next element an _ at index [expr $za+1] ?"

                    set hexBlock [lindex $list [expr $za +1]] ;# increase our hex character by plus one to check our next element

                    # switch checkTag "_"
                    #   This checks to see if the tag provided exists within the block given
                    # Cases:
                    #   1       | We have a valid tag sequence, return our hexBlock to the previous value, 
                    #             set the index to where we located the tag
                    #   default | The character was not a _ so we now check the previous characters
                    switch [checkTag "_" $hexBlock] {
                        1 {
        #                   puts "it is, so a valid tag match!"
        #                   puts "set our starting range!"
                            # decrease our za index to return to us to previous proper value
                            set hexBlock [lindex $list [expr $za -1]]
                            set locatedAt $za
                            #
                        }
                        default {
        #                   puts "No it's not, what about the previous?"
                            set hexBlock [lindex $list [expr $za -1]] ;# set our hexBlock to the previous index
                            # switch checkTag "_"
                            #   This checks to see if the tag provided exists within the block given
                            # Cases:
                            #   1       | We have a valid tag sequence, return our hexBlock to the previous value
                            #   default | the previous block was not a _
                            switch [checkTag "_" $hexBlock] {
                                1 {
        #                           puts "It is! so a valid match!"
                                    set hexBlock [lindex $list [expr $za +1]]
                                    ###
                                    # switch [llength $locatedAt]
                                    #   This checks to see if we have a starting range
                                    # Cases:
                                    #   0       | we have no starting range | break, as this will end up with malformed results
                                    #   1       | We have a valid tag sequence,
                                    #             appended our tag we've collected
                                    switch [llength $locatedAt] {
                                        0 { puts "We have no starting range" ; break }
                                        1 {
        #                                   puts "append range!" ;
                                            ## append the range of where we located our tag and where we are currently at
        #                                   lappend range $locatedAt $za ;# shows the discovered ranges of our tags
                                            lappend tagKeys [binary decode hex [lrange $list $locatedAt $za]]
                                            set locatedAt "" ;# reset our locatedAt for next loop iteration
                                            ##
                                        }
                                    }
                                }
                                default {
        #                           puts "No it wasn't"
                                    set hexChar [lindex $list [expr $za -1]]
                                }
                            }
                        }
                    }
                }
            } ;# end switch [checkTag "%" $hexBlock]
        incr za
        } ;# end foreach item
        set za 0
    } ;# end foreach line
    puts "Discovered tag: $tagKeys"
} ;# end proc

Output

% hexHunt
Discovered tag: %_hex_hunt_%