diff options
author | Helmut Grohne <helmut@subdivi.de> | 2013-03-24 18:05:24 +0100 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2013-03-24 18:05:24 +0100 |
commit | 5ba224a5aa2c8adb662136e2b8838d1cb0d32f27 (patch) | |
tree | ce9d5fa5aeb138cc24736d193005aa26a40fc0aa | |
parent | 614d6dd08948f25e86911e08efae53bf530d82d5 (diff) | |
download | ssdeep-5ba224a5aa2c8adb662136e2b8838d1cb0d32f27.tar.gz |
rename functions and export them
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.
-rw-r--r-- | fuzzy.c | 49 | ||||
-rw-r--r-- | fuzzy.h | 40 |
2 files changed, 64 insertions, 25 deletions
@@ -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; } @@ -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 * |