Refactored detection logic to include ports and a confidence score
This commit is contained in:
77
protocol/match.go
Normal file
77
protocol/match.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package protocol
|
||||
|
||||
// MatchPattern checks if the byte slice matches the magic string pattern.
|
||||
//
|
||||
// '?' matches any single character
|
||||
// '*' matches zero or more characters
|
||||
// '\' escapes special characters ('?', '*', '\')
|
||||
// All other characters must match exactly
|
||||
//
|
||||
// Returns true if all magic bytes are matched, even if input has extra bytes.
|
||||
func Match(magic string, input []byte) bool {
|
||||
return match(magic, input, 0, 0)
|
||||
}
|
||||
|
||||
// match is a recursive helper function that implements the matching logic
|
||||
func match(magic string, input []byte, magicIndex, inputIndex int) bool {
|
||||
// If we've reached the end of magic string, we've successfully matched all magic bytes
|
||||
// It doesn't matter if there are extra bytes in the input
|
||||
if magicIndex == len(magic) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle escape character
|
||||
if magic[magicIndex] == '\\' {
|
||||
// Check if there's a next character in magic
|
||||
if magicIndex+1 >= len(magic) {
|
||||
// Backslash at end of magic string - treat as literal backslash
|
||||
if inputIndex >= len(input) || input[inputIndex] != '\\' {
|
||||
return false
|
||||
}
|
||||
return match(magic, input, magicIndex+1, inputIndex+1)
|
||||
}
|
||||
|
||||
// Escape the next character - we need to match it literally
|
||||
escapedChar := magic[magicIndex+1]
|
||||
if inputIndex >= len(input) || input[inputIndex] != escapedChar {
|
||||
return false
|
||||
}
|
||||
// Skip both the backslash and the escaped character in magic, move one in input
|
||||
return match(magic, input, magicIndex+2, inputIndex+1)
|
||||
}
|
||||
|
||||
// If we've reached the end of input but not magic string
|
||||
if inputIndex == len(input) {
|
||||
// If we have '*' at the current position, it can match zero characters
|
||||
if magic[magicIndex] == '*' {
|
||||
return match(magic, input, magicIndex+1, inputIndex)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle '*' character - matches zero or more characters
|
||||
if magic[magicIndex] == '*' {
|
||||
// Try matching zero characters
|
||||
if match(magic, input, magicIndex+1, inputIndex) {
|
||||
return true
|
||||
}
|
||||
// Try matching one or more characters
|
||||
if inputIndex < len(input) && match(magic, input, magicIndex, inputIndex+1) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle '?' character - matches any single character
|
||||
if magic[magicIndex] == '?' {
|
||||
return match(magic, input, magicIndex+1, inputIndex+1)
|
||||
}
|
||||
|
||||
// Handle exact character match
|
||||
if magic[magicIndex] == input[inputIndex] {
|
||||
return match(magic, input, magicIndex+1, inputIndex+1)
|
||||
}
|
||||
|
||||
// No match found
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user