]> source.dussan.org Git - rspamd.git/commitdiff
Add Karp-Rabin algorithm for substrings search.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Sep 2015 14:04:24 +0000 (15:04 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 16 Sep 2015 14:04:24 +0000 (15:04 +0100)
src/libutil/str_util.c
src/libutil/str_util.h

index 2203cf0d4792537679e91ee48a8e63da0ceb158e..00f689bff4314ad5d3cb3afb3ab4d122ab500278 100644 (file)
@@ -1034,3 +1034,38 @@ rspamd_header_value_fold (const gchar *name,
 
        return res;
 }
+
+#define RKHASH(a, b, h) ((((h) - (a)*d) << 1) + (b))
+
+goffset
+rspamd_substring_search (const gchar *in, gsize inlen,
+               const gchar *srch, gsize srchlen)
+{
+       gint d, hash_srch, hash_in;
+       gsize i, j;
+
+       /* Preprocessing */
+       for (d = i = 1; i < srchlen; ++i) {
+               /* computes d = 2^(m-1) with the left-shift operator */
+               d = (d << 1);
+       }
+
+       for (hash_in = hash_srch = i = 0; i < srchlen; ++i) {
+               hash_srch = ((hash_srch << 1) + srch[i]);
+               hash_in = ((hash_in << 1) + in[i]);
+       }
+
+       /* Searching */
+       j = 0;
+       while (j <= inlen - srchlen) {
+
+               if (hash_srch == hash_in && memcmp (srch, in + j, srchlen) == 0) {
+                       return (goffset)j;
+               }
+
+               hash_in = RKHASH (in[j], in[j + srchlen], hash_in);
+               ++j;
+       }
+
+       return -1;
+}
index 1d0a9eadbe3813b96dfda7f778077079d64bcb94..3babc71f98450515affbe91ee89b4d2317bdf53e 100644 (file)
@@ -172,4 +172,15 @@ GString *rspamd_header_value_fold (const gchar *name,
                const gchar *value,
                guint fold_max);
 
+/**
+ * Search for a substring `srch` in the text `in` using Karp-Rabin algorithm
+ * @param in input
+ * @param inlen input len
+ * @param srch search string
+ * @param srchlen length of the search string
+ * @return position of the first substring match or (-1) if not found
+ */
+goffset rspamd_substring_search (const gchar *in, gsize inlen,
+       const gchar *srch, gsize srchlen);
+
 #endif /* SRC_LIBUTIL_STR_UTIL_H_ */