Skip to content

Instantly share code, notes, and snippets.

@gwillem
Created August 4, 2018 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gwillem/84228ec86953bf5c3ac2d0f01ad017d3 to your computer and use it in GitHub Desktop.
Save gwillem/84228ec86953bf5c3ac2d0f01ad017d3 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"testing"
"time"
"github.com/cloudflare/ahocorasick"
"github.com/cubicdaiya/bms"
yara "github.com/hillu/go-yara"
"github.com/kkdai/kmp"
"github.com/paddie/gokmp"
)
const (
runs = 10000
)
// This is https://raw.githubusercontent.com/gwillem/magento-malware-scanner/master/corpus/backend/3f34f51c981a9ddcfb0f41815c7dad49
var haystack = readFile("data.php")
// Random needle, doesn't exist in my haystack which is the most common case
var needle = "576ad4f370014dfb1d0f17b0e6855f22"
var yararules = getYaraRules()
func BenchmarkStringsContains(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = strings.Contains(haystack, needle)
}
}
func BenchmarkBMSSearch(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = bms.Search(haystack, needle)
}
}
func BenchmarkPaddieKMP(b *testing.B) {
kmp, _ := gokmp.NewKMP(needle)
for i := 0; i < b.N; i++ {
_ = kmp.FindStringIndex(haystack)
}
}
func BenchmarkKkdaiKMP(b *testing.B) {
for i := 0; i < b.N; i++ {
// _ = kmp.KMP(haystack, needle) // 1.46 ms
// _ = kmp.Strstr(haystack, needle) // 1.64 ms
_ = kmp.Strchr(haystack, needle) // 1.44 ms
}
}
func BenchmarkAhocorasick(b *testing.B) {
patterns := []string{needle}
testbytes := []byte(haystack)
m := ahocorasick.NewStringMatcher(patterns)
for i := 0; i < b.N; i++ {
_ = m.Match(testbytes)
}
}
func getYaraRules() *yara.Rules {
yc, _ := yara.NewCompiler()
namespace := "test"
yararule := `rule goyara_test {
strings: $ = "%s"
condition: any of them
}
`
yararule = fmt.Sprintf(yararule, needle)
yc.AddString(yararule, namespace)
rules, _ := yc.GetRules()
return rules
}
func BenchmarkYara(b *testing.B) {
testbytes := []byte(haystack)
timeout := 10 * time.Second
for i := 0; i < b.N; i++ {
yararules.ScanMem(testbytes, yara.ScanFlagsFastMode, timeout)
}
}
func readFile(fname string) string {
data, err := ioutil.ReadFile(fname)
if err != nil {
log.Fatal(err)
}
return string(data)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment