FFmpeg
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 
60 enum hashtype {
61 #define HASH_TYPE(TYPE, NAME, SIZE) TYPE,
64 };
65 
66 typedef struct AVHashContext {
67  void *ctx;
68  enum hashtype type;
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,
76 enum {
79 };
80 static_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,
85 enum {
88 };
89 
90 static const struct {
91  const char name[MAX_HASH_NAME_SIZE];
92  int size;
93 } hashdesc[] = {
94 #define HASH_DESC(TYPE, NAME, SIZE) [TYPE] = { NAME, SIZE },
96 };
97 
98 const char *av_hash_names(int i)
99 {
100  if (i < 0 || i >= NUM_HASHES) return NULL;
101  return hashdesc[i].name;
102 }
103 
104 const char *av_hash_get_name(const AVHashContext *ctx)
105 {
106  return hashdesc[ctx->type].name;
107 }
108 
110 {
111  return hashdesc[ctx->type].size;
112 }
113 
114 int av_hash_alloc(AVHashContext **ctx, const char *name)
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 
172 void 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 
214 void 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 
225 void 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 
235 void 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 }
HASH_DESC
#define HASH_DESC(TYPE, NAME, SIZE)
be
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it be(in the first position) for now. Options ------- Then comes the options array. This is what will define the user accessible options. For example
AVHashContext::crc
uint32_t crc
Definition: hash.c:70
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
av_sha512_final
void av_sha512_final(AVSHA512 *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha512.c:275
av_ripemd_alloc
struct AVRIPEMD * av_ripemd_alloc(void)
Allocate an AVRIPEMD context.
Definition: ripemd.c:46
AV_HASH_MAX_SIZE
#define AV_HASH_MAX_SIZE
Maximum value that av_hash_get_size() will currently return.
Definition: hash.h:156
AVCRC
uint32_t AVCRC
Definition: crc.h:46
name
const char name[MAX_HASH_NAME_SIZE]
Definition: hash.c:91
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:207
AVHashContext::ctx
void * ctx
Definition: hash.c:67
av_sha_init
av_cold int av_sha_init(AVSHA *ctx, int bits)
Initialize SHA-1 or SHA-2 hashing.
Definition: sha.c:274
av_sha512_alloc
struct AVSHA512 * av_sha512_alloc(void)
Allocate an AVSHA512 context.
Definition: sha512.c:44
hashdesc
static const struct @439 hashdesc[]
av_hash_final_b64
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
sha512.h
HASH_MAX_NAME_SIZE
#define HASH_MAX_NAME_SIZE(TYPE, NAME, SIZE)
Definition: hash.c:82
size
int size
Definition: hash.c:92
AVHashContext::type
enum hashtype type
Definition: hash.c:68
crc.h
av_hash_get_name
const char * av_hash_get_name(const AVHashContext *ctx)
Definition: hash.c:104
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
av_hash_final_bin
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
intreadwrite.h
ripemd.h
av_hash_alloc
int av_hash_alloc(AVHashContext **ctx, const char *name)
Allocate a hash context for the algorithm specified by name.
Definition: hash.c:114
to
const char * to
Definition: webvttdec.c:35
hashtype
hashtype
Definition: hash.c:60
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_murmur3_alloc
AVMurMur3 * av_murmur3_alloc(void)
Allocate an AVMurMur3 hash context.
Definition: murmur3.c:35
av_sha_final
void av_sha_final(AVSHA *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha.c:347
NULL
#define NULL
Definition: coverity.c:32
av_hash_names
const char * av_hash_names(int i)
Get the names of available hash algorithms.
Definition: hash.c:98
sha.h
av_hash_init
void av_hash_init(AVHashContext *ctx)
Initialize or reset a hash context.
Definition: hash.c:151
MAX_HASH_SIZE
@ MAX_HASH_SIZE
Definition: hash.c:78
adler32.h
av_hash_update
void av_hash_update(AVHashContext *ctx, const uint8_t *src, size_t len)
Update a hash context with additional data.
Definition: hash.c:172
av_murmur3_final
void av_murmur3_final(AVMurMur3 *c, uint8_t dst[16])
Finish hashing and output digest value.
Definition: murmur3.c:144
av_ripemd_init
av_cold int av_ripemd_init(AVRIPEMD *ctx, int bits)
Initialize RIPEMD hashing.
Definition: ripemd.c:466
base64.h
av_hash_freep
void av_hash_freep(AVHashContext **ctx)
Free hash context and set hash context pointer to NULL.
Definition: hash.c:248
av_adler32_update
AVAdler av_adler32_update(AVAdler adler, const uint8_t *buf, size_t len)
Calculate the Adler32 checksum of a buffer.
Definition: adler32.c:44
error.h
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
av_ripemd_final
void av_ripemd_final(AVRIPEMD *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: ripemd.c:548
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
av_sha_update
void av_sha_update(struct AVSHA *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha.c:315
av_hash_final
void av_hash_final(AVHashContext *ctx, uint8_t *dst)
Finalize a hash context and compute the actual hash value.
Definition: hash.c:193
av_crc_get_table
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:374
AVHashContext
Definition: hash.c:66
AVHashContext::crctab
const AVCRC * crctab
Definition: hash.c:69
av_sha_alloc
struct AVSHA * av_sha_alloc(void)
Allocate an AVSHA context.
Definition: sha.c:46
av_md5_init
void av_md5_init(AVMD5 *ctx)
Initialize MD5 hashing.
Definition: md5.c:143
AV_BASE64_SIZE
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition: base64.h:66
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_sha512_init
av_cold int av_sha512_init(AVSHA512 *ctx, int bits)
Initialize SHA-2 512 hashing.
Definition: sha512.c:192
md5.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
len
int len
Definition: vorbis_enc_data.h:426
av_md5_final
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Finish hashing and output digest value.
Definition: md5.c:188
hash.h
HASH_MAX_SIZE
#define HASH_MAX_SIZE(TYPE, NAME, SIZE)
Definition: hash.c:73
av_crc
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:392
av_md5_alloc
struct AVMD5 * av_md5_alloc(void)
Allocate an AVMD5 context.
Definition: md5.c:50
av_ripemd_update
void av_ripemd_update(AVRIPEMD *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: ripemd.c:516
av_hash_get_size
int av_hash_get_size(const AVHashContext *ctx)
Definition: hash.c:109
MAX_HASH_NAME_SIZE
@ MAX_HASH_NAME_SIZE
Definition: hash.c:87
av_base64_encode
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
av_md5_update
void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len)
Update hash value.
Definition: md5.c:153
HASH_TYPE
#define HASH_TYPE(TYPE, NAME, SIZE)
Definition: hash.c:61
AV_CRC_32_IEEE_LE
@ AV_CRC_32_IEEE_LE
Definition: crc.h:53
av_murmur3_init
void av_murmur3_init(AVMurMur3 *c)
Initialize or reinitialize an AVMurMur3 hash context.
Definition: murmur3.c:46
mem.h
av_murmur3_update
void av_murmur3_update(AVMurMur3 *c, const uint8_t *src, size_t len)
Update hash context with new data.
Definition: murmur3.c:95
av_hash_final_hex
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
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
HASHES
#define HASHES(ENTRY)
Definition: hash.c:43
avstring.h
murmur3.h
av_sha512_update
void av_sha512_update(AVSHA512 *ctx, const uint8_t *data, size_t len)
Update hash value.
Definition: sha512.c:243
snprintf
#define snprintf
Definition: snprintf.h:34
NUM_HASHES
@ NUM_HASHES
Definition: hash.c:63
src
#define src
Definition: vp8dsp.c:248