hash.h 8.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 */

21 22 23 24 25 26
/**
 * @file
 * @ingroup lavu_hash_generic
 * Generic hashing API
 */

27 28 29 30 31
#ifndef AVUTIL_HASH_H
#define AVUTIL_HASH_H

#include <stdint.h>

32 33
#include "version.h"

34 35 36
/**
 * @defgroup lavu_hash Hash Functions
 * @ingroup lavu_crypto
37 38 39 40 41 42
 * Hash functions useful in multimedia.
 *
 * Hash functions are widely used in multimedia, from error checking and
 * concealment to internal regression testing. libavutil has efficient
 * implementations of a variety of hash functions that may be useful for
 * FFmpeg and other multimedia applications.
43 44 45 46
 *
 * @{
 *
 * @defgroup lavu_hash_generic Generic Hashing API
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
 * An abstraction layer for all hash functions supported by libavutil.
 *
 * If your application needs to support a wide range of different hash
 * functions, then the Generic Hashing API is for you. It provides a generic,
 * reusable API for @ref lavu_hash "all hash functions" implemented in libavutil.
 * If you just need to use one particular hash function, use the @ref lavu_hash
 * "individual hash" directly.
 *
 * @section Sample Code
 *
 * A basic template for using the Generic Hashing API follows:
 *
 * @code
 * struct AVHashContext *ctx = NULL;
 * const char *hash_name = NULL;
 * uint8_t *output_buf = NULL;
 *
 * // Select from a string returned by av_hash_names()
 * hash_name = ...;
 *
 * // Allocate a hash context
 * ret = av_hash_alloc(&ctx, hash_name);
 * if (ret < 0)
 *     return ret;
 *
 * // Initialize the hash context
 * av_hash_init(ctx);
 *
 * // Update the hash context with data
 * while (data_left) {
 *     av_hash_update(ctx, data, size);
 * }
 *
 * // Now we have no more data, so it is time to finalize the hash and get the
 * // output. But we need to first allocate an output buffer. Note that you can
 * // use any memory allocation function, including malloc(), not just
 * // av_malloc().
 * output_buf = av_malloc(av_hash_get_size(ctx));
 * if (!output_buf)
 *     return AVERROR(ENOMEM);
 *
 * // Finalize the hash context.
 * // You can use any of the av_hash_final*() functions provided, for other
 * // output formats. If you do so, be sure to adjust the memory allocation
 * // above. See the function documentation below for the exact amount of extra
 * // memory needed.
 * av_hash_final(ctx, output_buffer);
 *
 * // Free the context
 * av_hash_freep(&ctx);
 * @endcode
 *
 * @section Hash Function-Specific Information
 * If the CRC32 hash is selected, the #AV_CRC_32_IEEE polynomial will be
 * used.
 *
 * If the Murmur3 hash is selected, the default seed will be used. See @ref
 * lavu_murmur3_seedinfo "Murmur3" for more information.
105 106 107 108
 *
 * @{
 */

109 110 111 112 113 114 115
/**
 * @example ffhash.c
 * This example is a simple command line application that takes one or more
 * arguments. It demonstrates a typical use of the hashing API with allocation,
 * initialization, updating, and finalizing.
 */

116 117 118 119 120 121
struct AVHashContext;

/**
 * Allocate a hash context for the algorithm specified by name.
 *
 * @return  >= 0 for success, a negative error code for failure
122 123 124
 *
 * @note The context is not initialized after a call to this function; you must
 * call av_hash_init() to do so.
125 126 127 128 129 130 131 132
 */
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.
 *
133 134
 * @param[in] i  Index of the hash algorithm, starting from 0
 * @return       Pointer to a static string or `NULL` if `i` is out of range
135 136 137 138 139 140 141 142
 */
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);

143
/**
144
 * Maximum value that av_hash_get_size() will currently return.
145
 *
146 147 148 149 150 151 152 153 154 155
 * You can use this if you absolutely want or need to use static allocation for
 * the output buffer and are fine with not supporting hashes newly added to
 * libavutil without recompilation.
 *
 * @warning
 * Adding new hashes with larger sizes, and increasing the macro while doing
 * so, will not be considered an ABI change. To prevent your code from
 * overflowing a buffer, either dynamically allocate the output buffer with
 * av_hash_get_size(), or limit your use of the Hashing API to hashes that are
 * already in FFmpeg during the time of compilation.
156
 */
157
#define AV_HASH_MAX_SIZE 64
158

159 160 161
/**
 * Get the size of the resulting hash value in bytes.
 *
162 163 164 165 166
 * The maximum value this function will currently return is available as macro
 * #AV_HASH_MAX_SIZE.
 *
 * @param[in]     ctx Hash context
 * @return            Size of the hash value in bytes
167 168 169 170 171
 */
int av_hash_get_size(const struct AVHashContext *ctx);

/**
 * Initialize or reset a hash context.
172 173
 *
 * @param[in,out] ctx Hash context
174 175 176 177 178
 */
void av_hash_init(struct AVHashContext *ctx);

/**
 * Update a hash context with additional data.
179 180 181 182
 *
 * @param[in,out] ctx Hash context
 * @param[in]     src Data to be added to the hash context
 * @param[in]     len Size of the additional data
183
 */
184
#if FF_API_CRYPTO_SIZE_T
185
void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, int len);
186 187 188
#else
void av_hash_update(struct AVHashContext *ctx, const uint8_t *src, size_t len);
#endif
189 190 191

/**
 * Finalize a hash context and compute the actual hash value.
192 193 194 195 196 197 198 199 200 201 202
 *
 * The minimum size of `dst` buffer is given by av_hash_get_size() or
 * #AV_HASH_MAX_SIZE. The use of the latter macro is discouraged.
 *
 * It is not safe to update or finalize a hash context again, if it has already
 * been finalized.
 *
 * @param[in,out] ctx Hash context
 * @param[out]    dst Where the final hash value will be stored
 *
 * @see av_hash_final_bin() provides an alternative API
203 204 205
 */
void av_hash_final(struct AVHashContext *ctx, uint8_t *dst);

206
/**
207 208 209 210 211 212 213 214 215 216 217
 * Finalize a hash context and store the actual hash value in a buffer.
 *
 * It is not safe to update or finalize a hash context again, if it has already
 * been finalized.
 *
 * If `size` is smaller than the hash size (given by av_hash_get_size()), the
 * hash is truncated; if size is larger, the buffer is padded with 0.
 *
 * @param[in,out] ctx  Hash context
 * @param[out]    dst  Where the final hash value will be stored
 * @param[in]     size Number of bytes to write to `dst`
218 219 220 221
 */
void av_hash_final_bin(struct AVHashContext *ctx, uint8_t *dst, int size);

/**
222 223 224 225 226 227
 * Finalize a hash context and store the hexadecimal representation of the
 * actual hash value as a string.
 *
 * It is not safe to update or finalize a hash context again, if it has already
 * been finalized.
 *
228
 * The string is always 0-terminated.
229 230 231 232 233 234 235
 *
 * If `size` is smaller than `2 * hash_size + 1`, where `hash_size` is the
 * value returned by av_hash_get_size(), the string will be truncated.
 *
 * @param[in,out] ctx  Hash context
 * @param[out]    dst  Where the string will be stored
 * @param[in]     size Maximum number of bytes to write to `dst`
236 237 238 239
 */
void av_hash_final_hex(struct AVHashContext *ctx, uint8_t *dst, int size);

/**
240 241 242 243 244 245
 * Finalize a hash context and store the Base64 representation of the
 * actual hash value as a string.
 *
 * It is not safe to update or finalize a hash context again, if it has already
 * been finalized.
 *
246
 * The string is always 0-terminated.
247 248 249 250 251 252 253
 *
 * If `size` is smaller than AV_BASE64_SIZE(hash_size), where `hash_size` is
 * the value returned by av_hash_get_size(), the string will be truncated.
 *
 * @param[in,out] ctx  Hash context
 * @param[out]    dst  Where the final hash value will be stored
 * @param[in]     size Maximum number of bytes to write to `dst`
254 255 256
 */
void av_hash_final_b64(struct AVHashContext *ctx, uint8_t *dst, int size);

257
/**
258 259 260
 * Free hash context and set hash context pointer to `NULL`.
 *
 * @param[in,out] ctx  Pointer to hash context
261 262 263
 */
void av_hash_freep(struct AVHashContext **ctx);

264 265 266 267 268
/**
 * @}
 * @}
 */

269
#endif /* AVUTIL_HASH_H */