需求分析

因为项目中需要检测一个文件是否被篡改,我采用了监测文件的MD5值。
MD5,简单地来说,就是文件的“指纹”。如果原始文件被修改了,那么MD5值也就会跟着发生变化,所以我们可以根据MD5是否变化来判断文件是否被改动。
感谢这位大牛的博客
计算文件的MD5值

实现

md5.h

/* MD5.H - header file for MD5C.C
*//* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.These notices must be retained in any copies of any part of this
documentation and/or software.
*/#ifndef MD5_H
#define MD5_H/* MD5 context. */
typedef struct {UINT4 state[4];                                   /* state (ABCD) */UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */unsigned char buffer[64];                         /* input buffer */
} MD5_CTX;void MD5Init(MD5_CTX*);
void MD5Update(MD5_CTX*, unsigned char*, unsigned int);
void MD5Final(unsigned char[16], MD5_CTX*);#endif

md5.cpp

/* MD5.C - RSA Data Security, Inc., MD5 message-digest algorithm
*//* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.These notices must be retained in any copies of any part of this
documentation and/or software.
*/#include "md5global.h"
#include "md5.h"/* Constants for MD5Transform routine.
*/#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21static void MD5Transform(UINT4[4], unsigned char[64]);
static void Encode(unsigned char*, UINT4*, unsigned int);
static void Decode(UINT4*, unsigned char*, unsigned int);
static void MD5_memcpy(POINTER, POINTER, unsigned int);
static void MD5_memset(POINTER, int, unsigned int);static unsigned char PADDING[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};/* F, G, H and I are basic MD5 functions.
*/
#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)))/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}
#define HH(a, b, c, d, x, s, ac) { \(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}
#define II(a, b, c, d, x, s, ac) { \(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \(a) = ROTATE_LEFT ((a), (s)); \(a) += (b); \}/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init(MD5_CTX* context) /* context */
{context->count[0] = context->count[1] = 0;/* Load magic initialization constants.*/context->state[0] = 0x67452301;context->state[1] = 0xefcdab89;context->state[2] = 0x98badcfe;context->state[3] = 0x10325476;
}/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update(MD5_CTX* context, unsigned char* input, unsigned int inputLen)
{unsigned int i, index, partLen;/* Compute number of bytes mod 64 */index = (unsigned int)((context->count[0] >> 3) & 0x3F);/* Update number of bits */if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3))context->count[1]++;context->count[1] += ((UINT4)inputLen >> 29);partLen = 64 - index;/* Transform as many times as possible.*/if (inputLen >= partLen) {MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);MD5Transform(context->state, context->buffer);for (i = partLen; i + 63 < inputLen; i += 64)MD5Transform(context->state, &input[i]);index = 0;}elsei = 0;/* Buffer remaining input */MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen - i);
}/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final(unsigned char digest[16], MD5_CTX* context)
{unsigned char bits[8];unsigned int index, padLen;/* Save number of bits */Encode(bits, context->count, 8);/* Pad out to 56 mod 64.*/index = (unsigned int)((context->count[0] >> 3) & 0x3f);padLen = (index < 56) ? (56 - index) : (120 - index);MD5Update(context, PADDING, padLen);/* Append length (before padding) */MD5Update(context, bits, 8);/* Store state in digest */Encode(digest, context->state, 16);/* Zeroize sensitive information.*/MD5_memset((POINTER)context, 0, sizeof(*context));
}/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform(UINT4 state[4], unsigned char block[64])
{UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];Decode(x, block, 64);/* Round 1 */FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 *//* Round 2 */GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 *//* Round 3 */HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 *//* Round 4 */II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */state[0] += a;state[1] += b;state[2] += c;state[3] += d;/* Zeroize sensitive information.*/MD5_memset((POINTER)x, 0, sizeof(x));
}/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode(unsigned char* output, UINT4* input, unsigned int len)
{unsigned int i, j;for (i = 0, j = 0; j < len; i++, j += 4) {output[j] = (unsigned char)(input[i] & 0xff);output[j + 1] = (unsigned char)((input[i] >> 8) & 0xff);output[j + 2] = (unsigned char)((input[i] >> 16) & 0xff);output[j + 3] = (unsigned char)((input[i] >> 24) & 0xff);}
}/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode(UINT4* output, unsigned char* input, unsigned int len)
{unsigned int i, j;for (i = 0, j = 0; j < len; i++, j += 4)output[i] = ((UINT4)input[j]) | (((UINT4)input[j + 1]) << 8) |(((UINT4)input[j + 2]) << 16) | (((UINT4)input[j + 3]) << 24);
}/* Note: Replace "for loop" with standard memcpy if possible.
*/static void MD5_memcpy(POINTER output, POINTER input, unsigned int len)
{unsigned int i;for (i = 0; i < len; i++)output[i] = input[i];
}/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset(POINTER output, int value, unsigned int len)
{unsigned int i;for (i = 0; i < len; i++)((char*)output)[i] = (char)value;
}

md5file.h

#ifndef MD5FILE_H
#define MD5FILE_H#include <string>std::string getFileMD5(const std::string& filename);#endif

md5file.cpp

#include "md5file.h"
#include "md5global.h"
#include "md5.h"#include <fstream>
#include <sstream>
#include <memory>
#include <iomanip>
#include <exception>std::string getFileMD5(const std::string& filename)
{std::ifstream fin(filename.c_str(), std::ifstream::in | std::ifstream::binary);if (fin){MD5_CTX context;MD5Init(&context);fin.seekg(0, fin.end);const auto fileLength = fin.tellg();fin.seekg(0, fin.beg);const int bufferLen = 8192;std::unique_ptr<unsigned char[]> buffer{ new unsigned char[bufferLen] {} };unsigned long long totalReadCount = 0;decltype(fin.gcount()) readCount = 0;// 读取文件内容,调用MD5Update()更新MD5值while (fin.read(reinterpret_cast<char*>(buffer.get()), bufferLen)){readCount = fin.gcount();totalReadCount += readCount;MD5Update(&context, buffer.get(), static_cast<unsigned int>(readCount));}// 处理最后一次读到的数据readCount = fin.gcount();if (readCount > 0){totalReadCount += readCount;MD5Update(&context, buffer.get(), static_cast<unsigned int>(readCount));}fin.close();// 数据完整性检查if (totalReadCount != fileLength){std::ostringstream oss;oss << "FATAL ERROR: read " << filename << " failed!" << std::ends;throw std::runtime_error(oss.str());}unsigned char digest[16];MD5Final(digest, &context);// 获取MD5std::ostringstream oss;for (int i = 0; i < 16; ++i){oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(digest[i]);}oss << std::ends;return std::move(oss.str());}else{std::ostringstream oss;oss << "FATAL ERROR: " << filename << " can't be opened" << std::ends;throw std::runtime_error(oss.str());}
}

md5global.h

/* GLOBAL.H - RSAREF types and constants
*//* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/#ifndef MD5_GLOBAL_H
#define MD5_GLOBAL_H/* POINTER defines a generic pointer type */
typedef unsigned char* POINTER;/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;#endif

main.cpp

#include <windows.h>
#include "md5file.h"
#include <iostream>
#include <winbase.h>using namespace std;#define PATH "D:\\Desktop\\Monitor_TangWeiKang\\UpgradedMonitoringMachine_TangWeiKang\\RecordingSeparation\\code\\VS2019\\DownloadWget\\record.txt"int main(void)
{while(1){//获取文件的MD5值//twk测试//std::cout << getFileMD5(PATH) << std::endl;string FileMD5 = getFileMD5(PATH);Sleep(1000);if(FileMD5.compare(getFileMD5(PATH))==0){cout << "文件没有被修改过" << endl;}else{cout << "文件被修改过l" << endl;}}return 0;
}

结果显示

在txt文件内添加和删除,MD5值是不断改变的

c++判断文件是否被修改(获取文件的MD5值)相关推荐

  1. php put怎么接收文件,php,restful_PHP PUT方式传文件的话,如何获取文件内容呢 ?,php,restful,http - phpStudy...

    PHP PUT方式传文件的话,如何获取文件内容呢 ? 最近因为在做前后端分离,后端PHP所有Api都使用RESTFul风格. 但是在使用PUT上传文件的时候,发现$_FILES没有文件信息(可能没有上 ...

  2. python文件目录无权限_python检查目录文件权限并修改目录文件权限的操作

    我就废话不多说了,还是直接看代码吧! # -*- coding: utf-8 -*- # @author flynetcn import sys, os, pwd, stat, datetime; L ...

  3. 最简单之获取app签名md5值

    网上教的大多数获取app签名md5值的方法都是通过生成jks还得打开黑窗口,有点小麻烦所以我用代码写了一个获取签名的方法 /*** MD5加密* @param byteStr 需要加密的内容* @re ...

  4. 前端判断文件后缀名_JS 获取文件后缀,判断文件类型(比如是否为图片格式)

    1.获取文件后缀H3I免费资源网 有时候我们需要通过文件名或者路径,得到该文件的后缀名(扩展名),可以通过如下方式进行截取:H3I免费资源网 //文件路径 var filePath = "f ...

  5. php 修改文件访问时间,PHP获取文件创建日期、修改日期、访问时间

    最近由于项目的需求需要对服务器上面的文件做一个时间的记录,接下来吾爱编程就为大家介绍一下PHP获取文件创建日期.修改日期.访问时间的方法,有需要的小伙伴可以参考一下: 1.常用代码: (1).file ...

  6. linux打开文件夹所有文件名,获取文件夹下的所有文件名 (linux windows)

    windows下获取文件夹下的所有文件名 1 #include "folder.hpp" 2 #include 3 4 void getFilesFromFolder(const ...

  7. linux 获取文件夹下文件信息,linux下获取文件夹下子文件列表

    linux下获取文件夹下子文件列表 预置条件: 1.只遍历当前目前,不遍历当前目录的子文件夹 2.根据用户提供的开始时间戳以及持续时间,返回在这个时间区间内被修改过的文件列表. 相关知识: 1.str ...

  8. 如何获取服务器上文件的hashcode,java获取文件hashcode

    java获取文件hashcode [2021-02-05 18:36:57]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace(&quo ...

  9. java获取文件编码_java如何获取文件编码格式

    1:简单判断是UTF-8或不是UTF-8,因为一般除了UTF-8之外就是GBK,所以就设置默认为GBK. 按照给定的字符集存储文件时,在文件的最开头的三个字节中就有可能存储着编码信息,所以,基本的原理 ...

  10. php 怎么查看文件类型信息,php获取文件类型和文件信息的方法

    php获取文件类型和文件信息的方法 发布于 2015-10-07 05:26:52 | 81 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext Pr ...

最新文章

  1. libsvm java api文档,libsvm-javaAPI
  2. 天猫双十一神话恐终结
  3. 99%高精度、毫秒级延迟,AI便携式神经假肢让截肢14年患者运动自如
  4. mysql创建非聚集索引_聚集索引和非聚集索引的区别
  5. 【开源项目】Socket服务端与客户端传输视频文件
  6. Tcl 语言改写Java题目-1
  7. python变量生命周期_python 变量定义及变量生命周期
  8. 屌丝程序员的那些事(一)-毕业那年
  9. vue ---- 将项目打包发布
  10. log4j指定日志文件目录
  11. 在sql中使用函数,遇到net.sf.jsqlparser.parser.ParseException异常
  12. 不是所有学计算机的都是肖奈,为什么《微微一笑很倾城》中贝微微肖奈学习都很拔尖,却都不考研...
  13. python监控网页_【小白教程】Python3监控网页
  14. CentOS7非桌面版关闭休眠和设置关闭盖子不休眠(server)
  15. 每日一诗词 —— 临江仙
  16. dedecms怎么改php版本_王者荣耀:管你版本怎么改,这几位峡谷常青树始终屹立不倒...
  17. IntelliJ IDEA的数据库管理工具实在太方便了
  18. lpop 原子_高负载量的Pd单原子催化剂用于选择性催化加氢反应
  19. 深度学习——Noisier2Noise
  20. Nim游戏、3的幂、4的幂

热门文章

  1. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
  2. linux脚本中怎么直接替换,linux-如何快速替换IP
  3. alsa 测试 linux_Linux低延迟服务器系统调优
  4. detachedcriteria查询去重_2020考研初试成绩查询:安徽研究生考试成绩查询入口
  5. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race
  6. 【sock_stream和sock_dgram】、 【AF_INET和AF_UNIX】
  7. locate 和 find
  8. IIS------如何安装IIS
  9. 【数据算法】Java实现二叉树存储以及遍历
  10. 实用ExtJS教程100例-002:MessageBox的三种用法