You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.0KB

  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. #include <stdint.h>
  21. #include "hash.h"
  22. #include "adler32.h"
  23. #include "crc.h"
  24. #include "md5.h"
  25. #include "murmur3.h"
  26. #include "sha.h"
  27. #include "avstring.h"
  28. #include "error.h"
  29. #include "intreadwrite.h"
  30. #include "mem.h"
  31. enum hashtype {
  32. MD5,
  33. MURMUR3,
  34. SHA160,
  35. SHA224,
  36. SHA256,
  37. CRC32,
  38. ADLER32,
  39. NUM_HASHES
  40. };
  41. typedef struct AVHashContext {
  42. void *ctx;
  43. enum hashtype type;
  44. const AVCRC *crctab;
  45. uint32_t crc;
  46. } AVHashContext;
  47. struct {
  48. const char *name;
  49. int size;
  50. } hashdesc[] = {
  51. [MD5] = {"MD5", 16},
  52. [MURMUR3] = {"murmur3", 16},
  53. [SHA160] = {"SHA160", 20},
  54. [SHA224] = {"SHA224", 28},
  55. [SHA256] = {"SHA256", 32},
  56. [CRC32] = {"CRC32", 4},
  57. [ADLER32] = {"adler32", 4},
  58. };
  59. const char *av_hash_names(int i)
  60. {
  61. if (i < 0 || i >= NUM_HASHES) return NULL;
  62. return hashdesc[i].name;
  63. }
  64. const char *av_hash_get_name(const AVHashContext *ctx)
  65. {
  66. return hashdesc[ctx->type].name;
  67. }
  68. int av_hash_get_size(const AVHashContext *ctx)
  69. {
  70. return hashdesc[ctx->type].size;
  71. }
  72. int av_hash_alloc(AVHashContext **ctx, const char *name)
  73. {
  74. AVHashContext *res;
  75. int i;
  76. *ctx = NULL;
  77. for (i = 0; i < NUM_HASHES; i++)
  78. if (av_strcasecmp(name, hashdesc[i].name) == 0)
  79. break;
  80. if (i >= NUM_HASHES) return AVERROR(EINVAL);
  81. res = av_mallocz(sizeof(*res));
  82. if (!res) return AVERROR(ENOMEM);
  83. res->type = i;
  84. switch (i) {
  85. case MD5: res->ctx = av_md5_alloc(); break;
  86. case MURMUR3: res->ctx = av_murmur3_alloc(); break;
  87. case SHA160:
  88. case SHA224:
  89. case SHA256: res->ctx = av_sha_alloc(); break;
  90. case CRC32: res->crctab = av_crc_get_table(AV_CRC_32_IEEE_LE); break;
  91. case ADLER32: break;
  92. }
  93. if (i != ADLER32 && i != CRC32 && !res->ctx) {
  94. av_free(res);
  95. return AVERROR(ENOMEM);
  96. }
  97. *ctx = res;
  98. return 0;
  99. }
  100. void av_hash_init(AVHashContext *ctx)
  101. {
  102. switch (ctx->type) {
  103. case MD5: av_md5_init(ctx->ctx); break;
  104. case MURMUR3: av_murmur3_init(ctx->ctx); break;
  105. case SHA160: av_sha_init(ctx->ctx, 160); break;
  106. case SHA224: av_sha_init(ctx->ctx, 224); break;
  107. case SHA256: av_sha_init(ctx->ctx, 256); break;
  108. case CRC32: ctx->crc = UINT32_MAX; break;
  109. case ADLER32: ctx->crc = 1; break;
  110. }
  111. }
  112. void av_hash_update(AVHashContext *ctx, const uint8_t *src, int len)
  113. {
  114. switch (ctx->type) {
  115. case MD5: av_md5_update(ctx->ctx, src, len); break;
  116. case MURMUR3: av_murmur3_update(ctx->ctx, src, len); break;
  117. case SHA160:
  118. case SHA224:
  119. case SHA256: av_sha_update(ctx->ctx, src, len); break;
  120. case CRC32: ctx->crc = av_crc(ctx->crctab, ctx->crc, src, len); break;
  121. case ADLER32: ctx->crc = av_adler32_update(ctx->crc, src, len); break;
  122. }
  123. }
  124. void av_hash_final(AVHashContext *ctx, uint8_t *dst)
  125. {
  126. switch (ctx->type) {
  127. case MD5: av_md5_final(ctx->ctx, dst); break;
  128. case MURMUR3: av_murmur3_final(ctx->ctx, dst); break;
  129. case SHA160:
  130. case SHA224:
  131. case SHA256: av_sha_final(ctx->ctx, dst); break;
  132. case CRC32: AV_WB32(dst, ctx->crc ^ UINT32_MAX); break;
  133. case ADLER32: AV_WB32(dst, ctx->crc); break;
  134. }
  135. }
  136. void av_hash_freep(AVHashContext **ctx)
  137. {
  138. if (*ctx)
  139. av_freep(&(*ctx)->ctx);
  140. av_freep(ctx);
  141. }