A tool for adding anime to your anidb list.
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.

62 lines
1.5KB

  1. #include <assert.h>
  2. #include "ed2k.h"
  3. /* https://wiki.anidb.net/Ed2k-hash */
  4. /* This is using the red method */
  5. #define ED2K_CHUNK_SIZE 9728000
  6. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  7. void ed2k_init(struct ed2k_ctx *ctx)
  8. {
  9. md4_init(&ctx->chunk_md4_ctx);
  10. md4_init(&ctx->hash_md4_ctx);
  11. ctx->byte_count = 0;
  12. }
  13. static void ed2k_hash_chunk(struct ed2k_ctx *ctx)
  14. {
  15. unsigned char chunk_hash[MD4_DIGEST_SIZE];
  16. md4_final(&ctx->chunk_md4_ctx, chunk_hash);
  17. md4_update(&ctx->hash_md4_ctx, chunk_hash, sizeof(chunk_hash));
  18. md4_init(&ctx->chunk_md4_ctx);
  19. }
  20. void ed2k_update(struct ed2k_ctx *ctx, const void *data, size_t data_len)
  21. {
  22. const char *bytes = (const char*)data;
  23. while (data_len) {
  24. size_t hdata_size = MIN(ED2K_CHUNK_SIZE -
  25. (ctx->byte_count % ED2K_CHUNK_SIZE), data_len);
  26. md4_update(&ctx->chunk_md4_ctx, bytes, hdata_size);
  27. ctx->byte_count += hdata_size;
  28. if (ctx->byte_count % ED2K_CHUNK_SIZE == 0)
  29. ed2k_hash_chunk(ctx);
  30. data_len -= hdata_size;
  31. bytes += hdata_size;
  32. }
  33. }
  34. void ed2k_final(struct ed2k_ctx *ctx, unsigned char *out_hash)
  35. {
  36. struct md4_ctx *md_ctx;
  37. if (ctx->byte_count < ED2K_CHUNK_SIZE) {
  38. /* File has only 1 chunk, so return the md4 hash of that chunk */
  39. md_ctx = &ctx->chunk_md4_ctx;
  40. } else {
  41. /* Else hash the md4 hashes, and return that hash */
  42. ed2k_hash_chunk(ctx); /* Hash the last partial chunk here */
  43. md_ctx = &ctx->hash_md4_ctx;
  44. }
  45. md4_final(md_ctx, out_hash);
  46. }