rename functions and export them
authorHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 17:05:24 +0000 (18:05 +0100)
committerHelmut Grohne <helmut@subdivi.de>
Sun, 24 Mar 2013 17:05:24 +0000 (18:05 +0100)
Use fuzzy_ as a prefix like all of the previous ones. Export fuzzy_new,
fuzzy_update, fuzzy_digest and fuzzy_free. These functions are
sufficient to put the caller in control and build an API similar to
Python's hashlib.

fuzzy.c
fuzzy.h

diff --git a/fuzzy.c b/fuzzy.c
index 2530872..19ba00b 100644 (file)
--- a/fuzzy.c
+++ b/fuzzy.c
@@ -100,7 +100,7 @@ struct blockhash_context {
        unsigned int dlen;
 };
 
-struct ssdeep_context {
+struct fuzzy_state {
        unsigned int bhstart, bhend;
        struct blockhash_context bh[NUM_BLOCKHASHES];
        size_t total_size;
@@ -109,9 +109,9 @@ struct ssdeep_context {
 
 #define SSDEEP_BS(index) (((uint32_t)MIN_BLOCKSIZE) << (index))
 
-static /*@only@*/ /*@null@*/ struct ssdeep_context *ssdeep_new(void) {
-       struct ssdeep_context *self;
-       if(NULL == (self = malloc(sizeof(struct ssdeep_context))))
+/*@only@*/ /*@null@*/ struct fuzzy_state *fuzzy_new(void) {
+       struct fuzzy_state *self;
+       if(NULL == (self = malloc(sizeof(struct fuzzy_state))))
                return NULL;
        self->bhstart = 0;
        self->bhend = 1;
@@ -123,7 +123,7 @@ static /*@only@*/ /*@null@*/ struct ssdeep_context *ssdeep_new(void) {
        return self;
 }
 
-static void ssdeep_try_fork_blockhash(struct ssdeep_context *self) {
+static void fuzzy_try_fork_blockhash(struct fuzzy_state *self) {
        struct blockhash_context *obh, *nbh;
        if(self->bhend >= NUM_BLOCKHASHES)
                return;
@@ -136,7 +136,7 @@ static void ssdeep_try_fork_blockhash(struct ssdeep_context *self) {
        ++self->bhend;
 }
 
-static void ssdeep_try_reduce_blockhash(struct ssdeep_context *self) {
+static void fuzzy_try_reduce_blockhash(struct fuzzy_state *self) {
        assert(self->bhstart < self->bhend);
        if(self->bhend - self->bhstart < 2)
                /* Need at least two working hashes. */
@@ -157,7 +157,7 @@ static void ssdeep_try_reduce_blockhash(struct ssdeep_context *self) {
 static const char *b64 =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-static void ssdeep_engine_step(struct ssdeep_context *self, unsigned char c) {
+static void fuzzy_engine_step(struct fuzzy_state *self, unsigned char c) {
        size_t h;
        unsigned int i;
        /* At each character we update the rolling hash and the normal hashes.
@@ -184,7 +184,7 @@ static void ssdeep_engine_step(struct ssdeep_context *self, unsigned char c) {
                if(unlikely(0 == self->bh[i].dlen)) {
                        /* Can only happen 30 times. */
                        /* First step for this blocksize. Clone next. */
-                       ssdeep_try_fork_blockhash(self);
+                       fuzzy_try_fork_blockhash(self);
                }
                if(self->bh[i].dlen < SPAMSUM_LENGTH - 1) {
                        /* We can have a problem with the tail overflowing. The
@@ -199,20 +199,19 @@ static void ssdeep_engine_step(struct ssdeep_context *self, unsigned char c) {
                        if(self->bh[i].dlen < SPAMSUM_LENGTH / 2)
                                self->bh[i].halfh = HASH_INIT;
                } else
-                       ssdeep_try_reduce_blockhash(self);
+                       fuzzy_try_reduce_blockhash(self);
        }
 }
 
-static int ssdeep_engine(struct ssdeep_context *self,
-               const unsigned char *buffer, size_t buffer_size) {
+int fuzzy_update(struct fuzzy_state *self, const unsigned char *buffer,
+               size_t buffer_size) {
        self->total_size += buffer_size;
        for( ;buffer_size > 0; ++buffer, --buffer_size)
-               ssdeep_engine_step(self, *buffer);
+               fuzzy_engine_step(self, *buffer);
        return 0;
 }
 
-static int ssdeep_digest(const struct ssdeep_context *self,
-               /*@out@*/ char *result) {
+int fuzzy_digest(const struct fuzzy_state *self, /*@out@*/ char *result) {
        unsigned int bi = self->bhstart;
        uint32_t h = roll_sum(&self->roll);
        int i, remain = FUZZY_MAX_RESULT - 1;
@@ -275,47 +274,47 @@ static int ssdeep_digest(const struct ssdeep_context *self,
        return 0;
 }
 
-static void ssdeep_free(/*@only@*/ struct ssdeep_context *self) {
+void fuzzy_free(/*@only@*/ struct fuzzy_state *self) {
        free(self);
 }
 
 int fuzzy_hash_buf(const unsigned char *buf, uint32_t buf_len,
                /*@out@*/ char *result) {
-       struct ssdeep_context *ctx;
+       struct fuzzy_state *ctx;
        int ret = -1;
-       if(NULL == (ctx = ssdeep_new()))
+       if(NULL == (ctx = fuzzy_new()))
                return -1;
-       if(ssdeep_engine(ctx, buf, buf_len) < 0)
+       if(fuzzy_update(ctx, buf, buf_len) < 0)
                goto out;
-       if(ssdeep_digest(ctx, result) < 0)
+       if(fuzzy_digest(ctx, result) < 0)
                goto out;
        ret = 0;
 out:
-       ssdeep_free(ctx);
+       fuzzy_free(ctx);
        return ret;
 }
 
 int fuzzy_hash_stream(FILE *handle, /*@out@*/ char *result) {
-       struct ssdeep_context *ctx;
+       struct fuzzy_state *ctx;
        unsigned char buffer[4096];
        size_t n;
        int ret = -1;
-       if(NULL == (ctx = ssdeep_new()))
+       if(NULL == (ctx = fuzzy_new()))
                return -1;
        for(;;) {
                n = fread(buffer, 1, 4096, handle);
                if(0 == n)
                        break;
-               if(ssdeep_engine(ctx, buffer, n) < 0)
+               if(fuzzy_update(ctx, buffer, n) < 0)
                        goto out;
        }
        if(ferror(handle) != 0)
                goto out;
-       if(ssdeep_digest(ctx, result) < 0)
+       if(fuzzy_digest(ctx, result) < 0)
                goto out;
        ret = 0;
 out:
-       ssdeep_free(ctx);
+       fuzzy_free(ctx);
        return ret;
 }
 
diff --git a/fuzzy.h b/fuzzy.h
index 32602e6..e08d9f1 100644 (file)
--- a/fuzzy.h
+++ b/fuzzy.h
@@ -30,6 +30,46 @@ extern "C" {
 #ifndef FUZZY_H
 #define FUZZY_H
 
+struct fuzzy_state;
+
+/**
+ * @brief Construct a fuzzy_state object and return it.
+ *
+ * To use it call fuzzy_update and fuzzy_digest on it. It must be disposed
+ * with fuzzy_free.
+ * @return the constructed fuzzy_state or NULL on failure
+ */
+extern /*@only@*/ /*@null@*/ struct fuzzy_state *fuzzy_new(void);
+
+/**
+ * @brief Feed the data contained in the given buffer to the state.
+ *
+ * When an error occurs, the state is undefined. In that case it must not be
+ * passed to any function besides fuzzy_free.
+ * @param buffer The data to be hashes
+ * @param buffer_size The length of the given buffer
+ * @return zero on success, non-zero on error
+ */
+extern int fuzzy_update(struct fuzzy_state *state, const unsigned char *buffer,
+               size_t buffer_size);
+
+/**
+ * @brief Obtain the fuzzy hash from the state.
+ *
+ * This operation does not change the state at all. It reports the hash for the
+ * concatenation of the data previously fed using fuzzy_update. 
+ * @param result Where the fuzzy hash is stored. This variable
+ * must be allocated to hold at least FUZZY_MAX_RESULT bytes.
+ * @return zero on success, non-zero on error
+ */
+extern int fuzzy_digest(const struct fuzzy_state *state,
+               /*@out@*/ char *result);
+
+/**
+ * @brief Dispose a fuzzy state.
+ */
+extern void fuzzy_free(/*@only@*/ struct fuzzy_state *state);
+
 /**
  * @brief Compute the fuzzy hash of a buffer
  *