FFmpeg
Loading...
Searching...
No Matches
hash.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <assert.h>
22#include <stddef.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <string.h>
26#include "hash.h"
27
28#include "adler32.h"
29#include "crc.h"
30#include "md5.h"
31#include "murmur3.h"
32#include "ripemd.h"
33#include "sha.h"
34#include "sha512.h"
35
36#include "avstring.h"
37#include "base64.h"
38#include "error.h"
39#include "intreadwrite.h"
40#include "mem.h"
41
42// ENTRY(HASH_TYPE, HASH_NAME, HASH_SIZE)
43#define HASHES(ENTRY) \
44 ENTRY(MD5, "MD5", 16) \
45 ENTRY(MURMUR3, "murmur3", 16) \
46 ENTRY(RIPEMD128, "RIPEMD128", 16) \
47 ENTRY(RIPEMD160, "RIPEMD160", 20) \
48 ENTRY(RIPEMD256, "RIPEMD256", 32) \
49 ENTRY(RIPEMD320, "RIPEMD320", 40) \
50 ENTRY(SHA160, "SHA160", 20) \
51 ENTRY(SHA224, "SHA224", 28) \
52 ENTRY(SHA256, "SHA256", 32) \
53 ENTRY(SHA512_224, "SHA512/224", 28) \
54 ENTRY(SHA512_256, "SHA512/256", 32) \
55 ENTRY(SHA384, "SHA384", 48) \
56 ENTRY(SHA512, "SHA512", 64) \
57 ENTRY(CRC32, "CRC32", 4) \
58 ENTRY(ADLER32, "adler32", 4) \
59
61#define HASH_TYPE(TYPE, NAME, SIZE) TYPE,
64};
65
66typedef struct AVHashContext {
67 void *ctx;
69 const AVCRC *crctab;
70 uint32_t crc;
72
73#define HASH_MAX_SIZE(TYPE, NAME, SIZE) \
74 HASH_MAX_SIZE_BEFORE_ ## TYPE, \
75 HASH_MAX_SIZE_UNTIL_ ## TYPE ## _MINUS_ONE = FFMAX(SIZE, HASH_MAX_SIZE_BEFORE_ ## TYPE) - 1,
76enum {
79};
80static_assert(AV_HASH_MAX_SIZE >= MAX_HASH_SIZE, "AV_HASH_MAX_SIZE needs to be updated!");
81
82#define HASH_MAX_NAME_SIZE(TYPE, NAME, SIZE) \
83 HASH_MAX_NAME_SIZE_BEFORE_ ## TYPE, \
84 HASH_MAX_NAME_SIZE_UNTIL_ ## TYPE ## _MINUS_ONE = FFMAX(sizeof(NAME), HASH_MAX_NAME_SIZE_BEFORE_ ## TYPE) - 1,
85enum {
88};
89
90static const struct {
92 int size;
93} hashdesc[] = {
94#define HASH_DESC(TYPE, NAME, SIZE) [TYPE] = { NAME, SIZE },
96};
97
98const char *av_hash_names(int i)
99{
100 if (i < 0 || i >= NUM_HASHES) return NULL;
101 return hashdesc[i].name;
102}
103
105{
106 return hashdesc[ctx->type].name;
107}
108
110{
111 return hashdesc[ctx->type].size;
112}
113
115{
116 AVHashContext *res;
117 int i;
118 *ctx = NULL;
119 for (i = 0; i < NUM_HASHES; i++)
120 if (av_strcasecmp(name, hashdesc[i].name) == 0)
121 break;
122 if (i >= NUM_HASHES) return AVERROR(EINVAL);
123 res = av_mallocz(sizeof(*res));
124 if (!res) return AVERROR(ENOMEM);
125 res->type = i;
126 switch (i) {
127 case MD5: res->ctx = av_md5_alloc(); break;
128 case MURMUR3: res->ctx = av_murmur3_alloc(); break;
129 case RIPEMD128:
130 case RIPEMD160:
131 case RIPEMD256:
132 case RIPEMD320: res->ctx = av_ripemd_alloc(); break;
133 case SHA160:
134 case SHA224:
135 case SHA256: res->ctx = av_sha_alloc(); break;
136 case SHA512_224:
137 case SHA512_256:
138 case SHA384:
139 case SHA512: res->ctx = av_sha512_alloc(); break;
140 case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break;
141 case ADLER32: break;
142 }
143 if (i != ADLER32 && i != CRC32 && !res->ctx) {
144 av_free(res);
145 return AVERROR(ENOMEM);
146 }
147 *ctx = res;
148 return 0;
149}
150
152{
153 switch (ctx->type) {
154 case MD5: av_md5_init(ctx->ctx); break;
155 case MURMUR3: av_murmur3_init(ctx->ctx); break;
156 case RIPEMD128: av_ripemd_init(ctx->ctx, 128); break;
157 case RIPEMD160: av_ripemd_init(ctx->ctx, 160); break;
158 case RIPEMD256: av_ripemd_init(ctx->ctx, 256); break;
159 case RIPEMD320: av_ripemd_init(ctx->ctx, 320); break;
160 case SHA160: av_sha_init(ctx->ctx, 160); break;
161 case SHA224: av_sha_init(ctx->ctx, 224); break;
162 case SHA256: av_sha_init(ctx->ctx, 256); break;
163 case SHA512_224: av_sha512_init(ctx->ctx, 224); break;
164 case SHA512_256: av_sha512_init(ctx->ctx, 256); break;
165 case SHA384: av_sha512_init(ctx->ctx, 384); break;
166 case SHA512: av_sha512_init(ctx->ctx, 512); break;
167 case CRC32: ctx->crc = UINT32_MAX; break;
168 case ADLER32: ctx->crc = 1; break;
169 }
170}
171
172void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
173{
174 switch (ctx->type) {
175 case MD5: av_md5_update(ctx->ctx, src, len); break;
176 case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break;
177 case RIPEMD128:
178 case RIPEMD160:
179 case RIPEMD256:
180 case RIPEMD320: av_ripemd_update(ctx->ctx, src, len); break;
181 case SHA160:
182 case SHA224:
183 case SHA256: av_sha_update(ctx->ctx, src, len); break;
184 case SHA512_224:
185 case SHA512_256:
186 case SHA384:
187 case SHA512: av_sha512_update(ctx->ctx, src, len); break;
188 case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break;
189 case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break;
190 }
191}
192
194{
195 switch (ctx->type) {
196 case MD5: av_md5_final(ctx->ctx, dst); break;
197 case MURMUR3: av_murmur3_final(ctx->ctx, dst); break;
198 case RIPEMD128:
199 case RIPEMD160:
200 case RIPEMD256:
201 case RIPEMD320: av_ripemd_final(ctx->ctx, dst); break;
202 case SHA160:
203 case SHA224:
204 case SHA256: av_sha_final(ctx->ctx, dst); break;
205 case SHA512_224:
206 case SHA512_256:
207 case SHA384:
208 case SHA512: av_sha512_final(ctx->ctx, dst); break;
209 case CRC32: AV_WB32(dst, ctx->crc ^ UINT32_MAX); break;
210 case ADLER32: AV_WB32(dst, ctx->crc); break;
211 }
212}
213
214void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size)
215{
216 uint8_t buf[AV_HASH_MAX_SIZE];
217 unsigned rsize = av_hash_get_size(ctx);
218
219 av_hash_final(ctx, buf);
220 memcpy(dst, buf, FFMIN(size, rsize));
221 if (size > rsize)
222 memset(dst + rsize, 0, size - rsize);
223}
224
225void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
226{
227 uint8_t buf[AV_HASH_MAX_SIZE];
228 unsigned rsize = av_hash_get_size(ctx), i;
229
230 av_hash_final(ctx, buf);
231 for (i = 0; i < FFMIN(rsize, size / 2); i++)
232 snprintf(dst + i * 2, size - i * 2, "%02x", buf[i]);
233}
234
235void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size)
236{
238 unsigned rsize = av_hash_get_size(ctx), osize;
239
240 av_hash_final(ctx, buf);
241 av_base64_encode(b64, sizeof(b64), buf, rsize);
242 osize = AV_BASE64_SIZE(rsize);
243 memcpy(dst, b64, FFMIN(osize, size));
244 if (size < osize)
245 dst[size - 1] = 0;
246}
247
249{
250 if (*ctx)
251 av_freep(&(*ctx)->ctx);
252 av_freep(ctx);
253}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
Public header for Adler-32 hash function implementation.
static AVFormatContext * ctx
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
Public header for CRC hash function implementation.
error code definitions
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
Calculate the Adler32 checksum of a buffer.
Definition adler32.c:44
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
Definition base64.c:147
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition base64.h:66
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition crc.c:389
uint32_t AVCRC
Definition crc.h:46
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition crc.c:421
@ AV_CRC_32_IEEE_LE
Definition crc.h:53
#define AVERROR(e)
Definition error.h:45
void av_hash_freep(AVHashContext **ctx)
Free hash context and set hash context pointer to NULL.
Definition hash.c:248
void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size)
Finalize a hash context and store the Base64 representation of the actual hash value as a string.
Definition hash.c:235
void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size)
Finalize a hash context and store the actual hash value in a buffer.
Definition hash.c:214
void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size)
Finalize a hash context and store the hexadecimal representation of the actual hash value as a string...
Definition hash.c:225
void av_hash_init(AVHashContext *ctx)
Initialize or reset a hash context.
Definition hash.c:151
void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
Update a hash context with additional data.
Definition hash.c:172
int av_hash_alloc(AVHashContext **ctx, const char *name)
Allocate a hash context for the algorithm specified by name.
Definition hash.c:114
const char * av_hash_names(int i)
Get the names of available hash algorithms.
Definition hash.c:98
void av_hash_final(AVHashContext *ctx, uint8_t *dst)
Finalize a hash context and compute the actual hash value.
Definition hash.c:193
#define AV_HASH_MAX_SIZE
Maximum value that av_hash_get_size() will currently return.
Definition hash.h:156
void av_md5_init(AVMD5 *ctx)
Initialize MD5 hashing.
Definition md5.c:143
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Finish hashing and output digest value.
Definition md5.c:188
struct AVMD5 * av_md5_alloc(void)
Allocate an AVMD5 context.
Definition md5.c:50
void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len)
Update hash value.
Definition md5.c:153
AVMurMur3 * av_murmur3_alloc(void)
Allocate an AVMurMur3 hash context.
Definition murmur3.c:35
void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, size_t len)
Update hash context with new data.
Definition murmur3.c:95
void av_murmur3_init(AVMurMur3 *c)
Initialize or reinitialize an AVMurMur3 hash context.
Definition murmur3.c:46
void av_murmur3_final(AVMurMur3 *c, uint8_t dst[16])
Finish hashing and output digest value.
Definition murmur3.c:144
void av_ripemd_final(AVRIPEMD *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition ripemd.c:548
av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits)
Initialize RIPEMD hashing.
Definition ripemd.c:466
void av_ripemd_update(AVRIPEMD *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition ripemd.c:516
struct AVRIPEMD * av_ripemd_alloc(void)
Allocate an AVRIPEMD context.
Definition ripemd.c:46
struct AVSHA512 * av_sha512_alloc(void)
Allocate an AVSHA512 context.
Definition sha512.c:44
av_cold int av_sha512_init(AVSHA512 *ctx, int bits)
Initialize SHA-2 512 hashing.
Definition sha512.c:192
void av_sha512_final(AVSHA512 *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha512.c:275
void av_sha512_update(AVSHA512 *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha512.c:243
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition sha.c:315
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition sha.c:46
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition sha.c:347
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition sha.c:274
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition avstring.c:208
static const struct @154042213135156076277066210352310164342317005367 hashdesc[]
@ MAX_HASH_SIZE
Definition hash.c:78
#define HASH_MAX_SIZE(TYPE, NAME, SIZE)
Definition hash.c:73
#define HASH_MAX_NAME_SIZE(TYPE, NAME, SIZE)
Definition hash.c:82
#define HASH_TYPE(TYPE, NAME, SIZE)
Definition hash.c:61
#define HASHES(ENTRY)
Definition hash.c:43
@ MAX_HASH_NAME_SIZE
Definition hash.c:87
int av_hash_get_size(const AVHashContext *ctx)
Definition hash.c:109
#define HASH_DESC(TYPE, NAME, SIZE)
const char * av_hash_get_name(const AVHashContext *ctx)
Definition hash.c:104
hashtype
Definition hash.c:60
@ NUM_HASHES
Definition hash.c:63
Generic hashing API.
#define AV_WB32(p, v)
#define FFMIN(a, b)
Definition macros.h:49
Public header for MD5 hash function implementation.
Memory handling functions.
Public header for MurmurHash3 hash function implementation.
const char * name
Definition qsvenc.c:142
Public header for RIPEMD hash function implementation.
Public header for SHA-512 implementation.
Public header for SHA-1 & SHA-256 hash function implementations.
#define snprintf
Definition snprintf.h:34
enum hashtype type
Definition hash.c:68
uint32_t crc
Definition hash.c:70
void * ctx
Definition hash.c:67
const AVCRC * crctab
Definition hash.c:69
#define av_free(p)
#define av_mallocz(s)
#define av_freep(p)
#define src
Definition vp8dsp.c:248
int size
int len