//
// Created by 阳坤 on 2022/3/1.
//参考:https://cloud.tencent.com/developer/article/1806329
//

#ifndef BYTESFLOW_OPENCV_MEDIA_MD5_H
#define BYTESFLOW_OPENCV_MEDIA_MD5_H

#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
typedef struct {
    unsigned int count[2];
    unsigned int state[4];
    unsigned char buffer[64];
} MD5_CTX;


#define F(x, y, z) ((x & y) | (~x & z))
#define G(x, y, z) ((x & z) | (y & ~z))
#define H(x, y, z) (x^y^z)
#define I(x, y, z) (y ^ (x | ~z))
#define ROTATE_LEFT(x, n) ((x << n) | (x >> (32-n)))
#define FF(a, b, c, d, x, s, ac) \
          { \
          a += F(b,c,d) + x + ac; \
          a = ROTATE_LEFT(a,s); \
          a += b; \
          }
#define GG(a, b, c, d, x, s, ac) \
          { \
          a += G(b,c,d) + x + ac; \
          a = ROTATE_LEFT(a,s); \
          a += b; \
          }
#define HH(a, b, c, d, x, s, ac) \
          { \
          a += H(b,c,d) + x + ac; \
          a = ROTATE_LEFT(a,s); \
          a += b; \
          }
#define II(a, b, c, d, x, s, ac) \
          { \
          a += I(b,c,d) + x + ac; \
          a = ROTATE_LEFT(a,s); \
          a += b; \
          }

/********************************************************
* 名    称: MD5Init()
* 功    能: 初始化MD5结构体
* 入口参数:
   context：要初始化的MD5结构体
* 出口参数: 无
*********************************************************/
void MD5Init(MD5_CTX *context);

/*********************************************************
* 名    称: MD5Update()
* 功    能: 将要加密的信息传递给初始化过的MD5结构体，无返回值
* 入口参数:
   context：初始化过了的MD5结构体
    input：需要加密的信息，可以任意长度
    inputLen：指定input的长度
* 出口参数: 无
*********************************************************/
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
/*********************************************************
* 名    称: MD5Update()
* 功    能: 将加密结果存储到，无返回值
* 入口参数:
   context：初始化过了的MD5结构体
    digest ：加密过的结果
* 出口参数: 无
*********************************************************/
void MD5Final(MD5_CTX *context, unsigned char digest[16]);

void MD5Transform(unsigned int state[4], unsigned char block[64]);

void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);

void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);

/**
 * 在线验证：http://www.metools.info/other/o21.html
 * 获取文件的 md5 值
 * @param filepath
 * @param dst
 */
int get_file_md5(const char * filepath,char *dst);

int md5_is_exactly_the_same(const char *src1,const char * src2);

#endif //BYTESFLOW_OPENCV_MEDIA_MD5_H
