21.10 Python 使用CRC32校验文件

news2024/12/26 12:03:40

CRC文件校验是一种用于验证文件完整性的方法,通过计算文件的CRC值并与预先计算的CRC校验值进行比较,来判断文件是否发生变化,此类功能可以用于验证一个目录中是否有文件发生变化,如果发生变化则我们可以将变化打印输出,该功能可用于实现对特定目录的验证。

首先实现文件与目录的遍历功能,递归输出文件或目录,在Python中有两种实现方式,我们可以通过自带的os.walk函数实现,也可以使用os.listdir实现,这里笔者依次封装两个函数,函数ordinary_all_file使用第一种方式,函数recursion_all_file使用第二种,这两种方式都返回_file列表,读者可使用列表接收输出数据集。

import os,hashlib,time,datetime
from zlib import crc32
import argparse

# 递归版遍历所有文件和目录
def recursion_all_file(rootdir):
    _file = []
    root = os.listdir(rootdir)
    for item in range(0,len(root)):
           path = os.path.join(rootdir,root[item])
           if os.path.isdir(path):
              _file.extend(recursion_all_file(path))
           if os.path.isfile(path):
              _file.append(path)

    for item in range(0,len(_file)):
        _file[item] = _file[item].replace("\\","/")
    return _file

# 通过自带OS库中的函数实现的目录遍历
def ordinary_all_file(rootdir):
    _file = []
    for root, dirs, files in os.walk(rootdir, topdown=False):
        for name in files:
            _file.append(os.path.join(root, name))
        for name in dirs:
            _file.append(os.path.join(root, name))
            
        for item in range(0,len(_file)):
            _file[item] = _file[item].replace("\\","/")
    return _file

针对计算方法此处也提供两种,第一种Calculation_md5sum使用hashlib模块内的md5()方法计算特定文件的MD5特征,第二种Calculation_crc32则使用zlib库中的crc32方法计算特定文件的CRC32值,如下所示。

# 通过hashlib模块读取文件并计算MD5值
def Calculation_md5sum(filename):
    try:
        fp = open(filename, 'rb')
        md5 = hashlib.md5()
        while True:
            temp = fp.read(8096)
            if not temp:
                break
            md5.update(temp)
        fp.close()
        return (md5.hexdigest())
    except Exception:
        return 0

# 计算目标CRC32
def Calculation_crc32(filename):
    try:
        with open(filename,"rb") as fp:
            crc = crc32(fp.read())
            while True:
                temp = fp.read(8196)
                if not temp:
                    break
            return crc
    except Exception:
        return 0
    return 0

在主函数中,我们通过argparse解析库传入参数,并分别实现三个功能,其中使用dump功能可以保存特定目录内文件的hash值到dump.json文件中,其次check功能可用于根据dump.json中的内容检查文件是否被改动过,最后的set则可用于批量设置文件的时间戳,这三类功能都属于较为常用的。

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--mode",dest="mode",help="指定需要使用的方法名称,(set/dump/check)")
    parser.add_argument("-d","--dir",dest="dir",help="指定一个需要遍历的文件目录(非文件)")
    parser.add_argument("-f","--files",dest="files",help="指定一个本地快照文件,或转储的文件名称")
    parser.add_argument("-t","--time",dest="time",help="指定需要统一修改的文件时间")
    args = parser.parse_args()

    # 保存快照: main.py --mode=dump -d "D:/lyshark" -f dump.json
    if args.mode == "dump" and args.dir and args.files:
        file = recursion_all_file(args.dir)
        fp = open(args.files,"w+")
        for item in file:
            Single = []
            Single.append(Calculation_crc32(item))
            Single.append(item)
            fp.write(str(Single) + "\n")
            print("[+] CRC: {} ---> 路径: {}".format(Single[0],Single[1]))
        fp.close()

    # 检查文件完整性: main.py --mode=check -d "D:/lyshark" -f dump.json
    elif args.mode == "check" and args.dir and args.files:
        fp = open(args.files,"r")
        for item in fp.readlines():
            _list = eval(item)

            # 取出json文件里的目录进行MD5计算
            _md5 = Calculation_crc32(_list[1])
            # 如果该文件的md5与数据库中的记录不一致,说明被修改了
            if _list[0] != _md5 and _md5 != 0:
                print("[-] 异常文件: {}".format(_list[1]))
            elif _md5 == 0:
                print("[x] 文件丢失: {}".format(_list[1]))

    # 设置文件修改时间: main.py --mode=set -d "D:/lyshark" -t "2019-01-01 11:22:30"
    elif args.mode == "set" and args.dir and args.time:
        _list = ordinary_all_file(args.dir)
        _time = int(time.mktime(time.strptime(args.time,"%Y-%m-%d %H:%M:%S")))
        for item in _list:
            os.utime(item,(_time, _time))
            print("[+] 时间戳: {} ---> 路径: {}".format(str(_time),item))
    else:
        parser.print_help()

指定mode模式为dump用于实现将特定文件计算CRC特征,并将该特征保存至dump.json文件内,如下图所示;

指定mode模式为check并指定转存之前的dump.json文件,则可用于验证当前目录下是否存在异常文件,如果文件特征值发生了变化则会提示异常文件,而如果文件被删除或被重命名则会输出文件丢失,如下图所示;

指定mode模式为set则可实现对特定目录内特定文件修改时间参数,例如将d://lyshark目录内的文件全部重置时间戳为2019-01-01 11:22:30则可执行如下命令,执行后读者可自行观察文件时间变化,如下图所示;

文件与目录遍历功能,不仅可以用于对文件的特征扫描,还可以与fopen等函数实现对特定文件内特定内容的扫描,如下是一段实现对文件内特定目录的关键字扫描,运行后读者通过传入需要扫描的路径,扫描的关键字,以及需要扫描文件类型即可。

import os,re
import argparse

def spider(script_path,script_type):
    final_files = []
    for root, dirs, files in os.walk(script_path, topdown=False):
            for fi in files:
                dfile = os.path.join(root, fi)
                if dfile.endswith(script_type):
                    final_files.append(dfile.replace("\\","/"))
    print("[+] 共找到了 {} 个 {} 文件".format(len(final_files),script_type))
    return final_files

def scanner(files_list,func):
    for item in files_list:
        fp = open(item, "r",encoding="utf-8")
        data = fp.readlines()
        for line in data:
            Code_line = data.index(line) + 1
            Now_code = line.strip("\n")
            #for unsafe in ["system", "insert", "include", "eval","select \*"]:
            for unsafe in [func]:
                flag = re.findall(unsafe, Now_code)
                if len(flag) != 0:
                    print("函数: {} ---> 函数所在行: {} ---> 路径: {} " .\
                          format(flag,Code_line,item))

if __name__ == "__main__":
    # 使用方式: main.py -p "D://lyshark" -w eval -t .php
    parser = argparse.ArgumentParser()
    parser.add_argument("-p","--path",dest="path",help="设置扫描路径")
    parser.add_argument("-w","--word",dest="func",help="设置检索的关键字")
    parser.add_argument("-t","--type",dest="type",default=".php",help="设置扫描文件类型,默认php")
    args = parser.parse_args()
    if args.path and args.func:
        ret = spider(args.path, args.type)
        scanner(ret, args.func)
    else:
        parser.print_help()

如下图所示,我们通过传入d://lyshark以及关键字gumbo_normalized_tagname并设置扫描后缀类型*.c当程序运行后,即可输出该目录下所有符合条件的文件,并输出函数所在行,这有利于我们快速跳转并分析数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1144027.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初次学习dubbo记录

---------------------------------------10.17---------------------------------------- 集群和分布式概念 集群:很多"人"做的相同的一件事,即使有一个人挂掉了,也不会对系统造成致命影响 分布式:很多"人"…

外卖小程序:技术实现与关键代码

在当今数字化的餐饮市场中,外卖小程序扮演着重要的角色。这些应用程序通过技术实现点餐、支付和配送,为用户提供方便快捷的服务。下面我们来深入探讨构建外卖小程序的关键技术要点和代码示例。 1. 前端开发 前端是用户与应用程序交互的接口&#xff0…

三年轻量:腾讯云3年轻量2核2G4M服务器366上三年时长

腾讯云轻量应用服务器三年特价,3年轻量2核2G4M服务器,2023双十一优惠价格366元三年,自带4M公网带宽,下载速度可达512KB/秒,300GB月流量,50GB SSD盘系统盘,阿腾云atengyun.com分享腾讯云轻量2核2…

晚上没事干又想利用时间赚钱,那就做副业,不要再懒了

很多朋友白天上班工作不是那么累,晚上下班后又比较空闲,如果一晚上不想被游戏、短视频、电影填满的话,那可以做一些兼职副业来扩宽收入来源,不仅充分利用了时间,还赚取了额外的收入。 晚上能做的兼职副业可太多了&…

AQS 为什么要使用双向链表?

双向链表 双向链表的特点是它有两个指针,一个指针指向前置节点,一个指针指向后继节点。所以,双向链表可以支持 常量 O(1) 时间复杂度的情况下找到前驱结点,基于这样的特点。双向链表在插入和删除操作的时候,要比单向链…

基于STM32两轮自平衡小车系统设计与控制

**单片机设计介绍,1650【毕设课设】基于STM32两轮自平衡小车系统设计与控制 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序文档 六、 文章目录 一 概要 主控芯片用的是100脚的STM32F103VET6,陀螺仪用的是MPU6050,电机…

基础课12——数据采集

数据采集是指从传感器和其它待测设备等模拟和数字被测单元中自动采集非电量或者电量信号,送到上位机中进行分析处理。数据采集系统是结合基于计算机或者其他专用测试平台的测量软硬件产品来实现灵活的、用户自定义的测量系统。采集一般是采样方式,即隔一定时间(称采样周期)对同…

线性表的定义和基本操作

线性表的定义和基本操作 一、线性表的定义 线性表(Linear List)是具有相同数据类型的n(n>0)个数据元素的有限序列,其中n为表长,当n0时线性表是一个空表。若用L命名线性表,则其一般表示为 L (a1,a2,...,ai,ai1,.…

防止请求重复提交:注解+拦截器的实现方案

文章目录 了解请求重复提交解决思路具体实现 了解请求重复提交 请求重复提交是指用户在一次请求还未处理完成时,重复提交了相同的请求。这种情况通常发生在网络延迟、用户误操作或系统性能不佳等情况下。 请求重复提交可能会导致以下问题和影响: 数据不…

学习笔记:二分图

二分图 引入 二分图又被称为二部图。 二分图就是可以二分答案的图。 二分图是节点由两个集合组成,且两个集合内部没有边的图。换言之,存在一种方案,将节点划分成满足以上性质的两个集合。 性质 如果两个集合中的点分别染成黑色和白色&am…

C语言之 结构体,枚举,联合

目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3 特殊的声明 1.4 结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7 修改默认对齐数 1.8 结构体传参 2. 位段 2.1 什么是位段 2.2位段的内存分配 2.3 位段的跨平台问题 3. 枚举 3.1 枚举类型…

Mybatis简介(二)

1、多表映射 简介一 链接 对于数据库的操作,很多时候我们都是在多表的基础上进行操作的,在这里讲一下多表属性值与列名映射。 案例:这里有一个订单表和一个客户表 CREATE TABLE t_customer (customer_id INT NOT NULL AUTO_INCREMENT, cus…

在 Elasticsearch 中丰富你的 Elasticsearch 文档

作者:David Pilato 对于 Elasticsearch,我们知道联接应该在 “索引时” 而不是查询时完成。 本博文是一系列三篇博文的开始,因为我们可以在 Elastic 生态系统中采取多种方法。 我们将介绍如何在 Elasticsearch 中做到这一点。 下一篇博文将介…

node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)

文章目录 ⭐前言⭐ 环境准备⭐ 实现过程⭐ mysql 配置⭐路由前的准备⭐账号注册生成token⭐账号登录生成token⭐token登录 ⭐ 自测过程截图⭐总结⭐结束 ⭐前言 大家好,我是yma16,本文分享关于node实战——后端koa项目配置jwt实现登录注册(n…

1230. K倍区间(前缀和)

题目&#xff1a; 1230. K倍区间 - AcWing题库 突破口&#xff1a; 区间遍历枚举一般先枚举右端点&#xff0c;再枚举左端点&#xff0c;注意由右端点限制左端点 思路&#xff1a;1.暴力 #include<cstdio> #include<iostream> #include<algorithm> #incl…

Win 7 VPN拨号错误734.

正在验证用户名和密码错误 734: PPP 链接控制协议终止。 如果您继续收到错误信息&#xff0c;您可以启用日志记录来做分析。 其他电脑拨号都成功.就这个电脑不行.找了很久,修改之后报好成功 ************************** 找到是跟下面两个两个注册表信息有关,尤其是第一个我…

基于Pytest+Requests+Allure实现接口自动化测试!

一、整体结构 框架组成&#xff1a;pytestrequestsallure设计模式&#xff1a; 关键字驱动项目结构&#xff1a; 工具层&#xff1a;api_keyword/参数层&#xff1a;params/用例层&#xff1a;case/数据驱动&#xff1a;data_driver/数据层&#xff1a;data/逻辑层&#xff1a…

75 寻找旋转排序数组中的最小值

寻找旋转排序数组中的最小值 题解1 一次循环(正确理解题意)题解2 二分 已知一个长度为 n 的数组&#xff0c;预先按照 升序排列&#xff0c;经由 1 到 n 次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组 nums [0,1,2,4,5,6,7] 在变化后可能得到&#xff1a; …

刚刚:2023阿里云双十一优惠活动上线了!

2023阿里云双十一优惠活动「金秋云创季」开始啦&#xff0c;10月27日到10月31日可以领满减优惠&#xff0c;到11月1日和11月11日之间可以购买云服务器等产品&#xff0c;11.12到11.30日赢最高百万上云抵扣金&#xff0c;阿里云百科aliyunbaike.com分享2023阿里云双十一优惠活动…

Xray的简单使用

xray 简介 xray 是一款功能强大的安全评估工具&#xff0c;由多名经验丰富的一线安全从业者呕心打造而成&#xff0c;主要特性有: 检测速度快。发包速度快; 漏洞检测算法效率高。支持范围广。大至 OWASP Top 10 通用漏洞检测&#xff0c;小至各种 CMS 框架 POC&#xff0c;均…