diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2013-05-09 20:10:47 +0400 |
---|---|---|
committer | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2013-05-13 23:42:37 +0400 |
commit | 7d1d596817e8578cca1605f37342a4986bf70027 (patch) | |
tree | 99a29406604e0e6efe13c722905aafe857d91d00 /libavutil | |
parent | 86215c326e56e50047e6a818327bc7589995975d (diff) |
Add a generic hash API.
Also use this API in framemd5.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/Makefile | 1 | ||||
-rw-r--r-- | libavutil/hash.c | 154 | ||||
-rw-r--r-- | libavutil/hash.h | 78 |
3 files changed, 233 insertions, 0 deletions
diff --git a/libavutil/Makefile b/libavutil/Makefile index e6feccc5fe..f7852ee224 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -81,6 +81,7 @@ OBJS = adler32.o \ file.o \ float_dsp.o \ frame.o \ + hash.o \ hmac.o \ imgutils.o \ intfloat_readwrite.o \ diff --git a/libavutil/hash.c b/libavutil/hash.c new file mode 100644 index 0000000000..481010dee8 --- /dev/null +++ b/libavutil/hash.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdint.h> +#include "hash.h" + +#include "adler32.h" +#include "crc.h" +#include "md5.h" +#include "murmur3.h" +#include "sha.h" + +#include "avstring.h" +#include "error.h" +#include "intreadwrite.h" +#include "mem.h" + +enum hashtype { + MD5, + MURMUR3, + SHA160, + SHA224, + SHA256, + CRC32, + ADLER32, + NUM_HASHES +}; + +typedef struct AVHashContext { + void *ctx; + enum hashtype type; + const AVCRC *crctab; + uint32_t crc; +} AVHashContext; + +struct { + const char *name; + int size; +} hashdesc[] = { + [MD5] = {"MD5", 16}, + [MURMUR3] = {"murmur3", 16}, + [SHA160] = {"SHA160", 20}, + [SHA224] = {"SHA240", 28}, + [SHA256] = {"SHA256", 32}, + [CRC32] = {"CRC32", 4}, + [ADLER32] = {"adler32", 4}, +}; + +const char *av_hash_names(int i) +{ + if (i < 0 || i >= NUM_HASHES) return NULL; + return hashdesc[i].name; +} + +const char *av_hash_get_name(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].name; +} + +int av_hash_get_size(const AVHashContext *ctx) +{ + return hashdesc[ctx->type].size; +} + +int av_hash_alloc(AVHashContext **ctx, const char *name) +{ + AVHashContext *res; + int i; + *ctx = NULL; + for (i = 0; i < NUM_HASHES; i++) + if (av_strcasecmp(name, hashdesc[i].name) == 0) + break; + if (i >= NUM_HASHES) return AVERROR(EINVAL); + res = av_mallocz(sizeof(*res)); + if (!res) return AVERROR(ENOMEM); + res->type = i; + switch (i) { + case MD5: res->ctx = av_md5_alloc(); break; + case MURMUR3: res->ctx = av_murmur3_alloc(); break; + case SHA160: + case SHA224: + case SHA256: res->ctx = av_sha_alloc(); break; + case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE); break; + case ADLER32: break; + } + if (i != ADLER32 && i != CRC32 && !res->ctx) { + av_free(res); + return AVERROR(ENOMEM); + } + *ctx = res; + return 0; +} + +void av_hash_init(AVHashContext *ctx) +{ + switch (ctx->type) { + case MD5: av_md5_init(ctx->ctx); break; + case MURMUR3: av_murmur3_init(ctx->ctx); break; + case SHA160: av_sha_init(ctx->ctx, 160); break; + case SHA224: av_sha_init(ctx->ctx, 224); break; + case SHA256: av_sha_init(ctx->ctx, 256); break; + case CRC32: + case ADLER32: ctx->crc = 0; break; + } +} + +void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len) +{ + switch (ctx->type) { + case MD5: av_md5_update(ctx->ctx, src, len); break; + case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break; + case SHA160: + case SHA224: + case SHA256: av_sha_update(ctx->ctx, src, len); break; + case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break; + case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break; + } +} + +void av_hash_final(AVHashContext *ctx, uint8_t *dst) +{ + switch (ctx->type) { + case MD5: av_md5_final(ctx->ctx, dst); break; + case MURMUR3: av_murmur3_final(ctx->ctx, dst); break; + case SHA160: + case SHA224: + case SHA256: av_sha_final(ctx->ctx, dst); break; + case CRC32: + case ADLER32: AV_WL32(dst, ctx->crc); break; + } +} + +void av_hash_freep(AVHashContext **ctx) +{ + if (*ctx) + av_freep(&(*ctx)->ctx); + av_freep(ctx); +} diff --git a/libavutil/hash.h b/libavutil/hash.h new file mode 100644 index 0000000000..7ecb3e72a9 --- /dev/null +++ b/libavutil/hash.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_HASH_H +#define AVUTIL_HASH_H + +#include <stdint.h> + +struct AVHashContext; + +/** + * Allocate a hash context for the algorithm specified by name. + * + * @return >= 0 for success, a negative error code for failure + * @note The context is not initialized, you must call av_hash_init(). + */ +int av_hash_alloc(struct AVHashContext **ctx, const char *name); + +/** + * Get the names of available hash algorithms. + * + * This function can be used to enumerate the algorithms. + * + * @param i index of the hash algorithm, starting from 0 + * @return a pointer to a static string or NULL if i is out of range + */ +const char *av_hash_names(int i); + +/** + * Get the name of the algorithm corresponding to the given hash context. + */ +const char *av_hash_get_name(const struct AVHashContext *ctx); + +/** + * Get the size of the resulting hash value in bytes. + * + * The pointer passed to av_hash_final have space for at least this many bytes. + */ +int av_hash_get_size(const struct AVHashContext *ctx); + +/** + * Initialize or reset a hash context. + */ +void av_hash_init(struct AVHashContext *ctx); + +/** + * Update a hash context with additional data. + */ +void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len); + +/** + * Finalize a hash context and compute the actual hash value. + */ +void av_hash_final(struct AVHashContext *ctx, uint8_t *dst); + +/** + * Free hash context. + */ +void av_hash_freep(struct AVHashContext **ctx); + +#endif /* AVUTIL_HASH_H */ |