一、概述
本系统旨在利用区块链技术验证两个文件(try.txt
和 try_copy.txt
)的内容是否一致,以检测文件是否被篡改。通过将文件的哈希值存储在区块链的不同区块中,并对区块链进行有效性验证,结合文件哈希值的比较,实现文件内容的完整性检查。
二、功能特性
- 区块链基础功能:实现了基本的区块链结构,包含区块的创建、链接以及区块链的有效性验证。
- 文件哈希计算:能够计算指定文件的 SHA - 256 哈希值,用于唯一标识文件内容。
- 文件内容比较:通过比较两个文件的哈希值,判断文件内容是否一致。
- 数据完整性验证:对区块链进行验证,确保存储的文件哈希信息未被篡改。
三、代码结构与模块说明
(一)模块导入
收起
python
import hashlib
import time
hashlib
:用于进行哈希运算,本系统使用 SHA - 256 算法。time
:用于获取当前时间戳,作为区块创建时间的标识。
(二)Block
类
收起
python
class Block:
def __init__(self, index, timestamp, data, previous_hash):
self.index = index
self.timestamp = timestamp
self.data = data
self.previous_hash = previous_hash
self.hash = self.calculate_hash()
def calculate_hash(self):
block_string = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}"
return hashlib.sha256(block_string.encode()).hexdigest()
- 功能:表示区块链中的单个区块。
- 属性:
index
:区块在区块链中的索引,标识其位置。timestamp
:区块创建时的时间戳。data
:区块存储的数据,这里为文件的路径和哈希值信息。previous_hash
:前一个区块的哈希值,用于将区块链接成链。hash
:当前区块的哈希值,通过calculate_hash
方法计算得到。
- 方法:
calculate_hash()
:将区块的索引、时间戳、数据和前一个哈希值拼接成字符串,使用 SHA - 256 算法计算哈希值。
(三)Blockchain
类
收起
python
class Blockchain:
def __init__(self):
self.chain = [self.create_genesis_block()]
def create_genesis_block(self):
return Block(0, time.time(), "Genesis Block", "0")
def get_latest_block(self):
return self.chain[-1]
def add_block(self, new_block):
new_block.previous_hash = self.get_latest_block().hash
new_block.hash = new_block.calculate_hash()
self.chain.append(new_block)
def is_chain_valid(self):
for i in range(1, len(self.chain)):
current_block = self.chain[i]
previous_block = self.chain[i - 1]
if current_block.hash != current_block.calculate_hash():
return False
if current_block.previous_hash != previous_block.hash:
return False
return True
- 功能:表示整个区块链,负责管理区块的添加和区块链的验证。
- 属性:
chain
:存储区块链中所有区块的列表,初始包含一个创世区块。
- 方法:
create_genesis_block()
:创建区块链的第一个区块,即创世区块。get_latest_block()
:返回区块链中最后一个区块。add_block(new_block)
:将新的区块添加到区块链中,更新新区块的前一个哈希值并重新计算其哈希值。is_chain_valid()
:验证区块链的有效性,检查每个区块的哈希值和前一个哈希值是否正确。
(四)calculate_file_hash
函数
收起
python
def calculate_file_hash(file_path):
try:
hash_object = hashlib.sha256()
with open(file_path, 'rb') as file:
for chunk in iter(lambda: file.read(4096), b""):
hash_object.update(chunk)
return hash_object.hexdigest()
except FileNotFoundError:
print(f"文件 {file_path} 未找到。")
return None
- 功能:计算指定文件的 SHA - 256 哈希值。
- 参数:
file_path
:要计算哈希值的文件的路径。
- 返回值:
- 若文件存在,返回文件的十六进制哈希值字符串。
- 若文件不存在,打印错误信息并返回
None
。
(五)主程序
收起
python
blockchain = Blockchain()
file1_path = r"D:\MyPythonProject\Deep_Learning\Blockchain\try.txt"
file2_path = r"D:\MyPythonProject\Deep_Learning\Blockchain\try_copy.txt"
file1_hash = calculate_file_hash(file1_path)
if file1_hash:
block1 = Block(1, time.time(), f"File: {file1_path}, Hash: {file1_hash}", "")
blockchain.add_block(block1)
file2_hash = calculate_file_hash(file2_path)
if file2_hash:
block2 = Block(2, time.time(), f"File: {file2_path}, Hash: {file2_hash}", "")
blockchain.add_block(block2)
if blockchain.is_chain_valid():
if file1_hash == file2_hash:
print("两个文件内容一致,未被篡改。")
else:
print("两个文件内容不一致,可能存在篡改。")
else:
print("区块链验证失败,数据可能存在问题。")
- 功能:创建区块链实例,计算两个文件的哈希值,将文件信息添加到区块链中,验证区块链的有效性,并比较两个文件的哈希值,输出验证结果。
四、使用方法
- 环境准备:确保 Python 环境已安装,且可以正常使用
hashlib
和time
模块。 - 文件准备:将需要比较的两个文件(
try.txt
和try_copy.txt
)放置在指定路径下(D:\MyPythonProject\Deep_Learning\Blockchain
)。 - 运行代码:将上述代码保存为 Python 文件(如
file_verification.py
),在命令行中运行该文件:
收起
bash
python file_verification.py
- 查看结果:根据程序输出的信息,判断两个文件的内容是否一致以及区块链数据是否有效。
五、注意事项
- 文件路径:确保文件路径正确,否则会提示文件未找到的错误信息。
- 哈希算法:本系统使用 SHA - 256 哈希算法,不同的哈希算法可能会导致不同的哈希值结果。
- 区块链安全性:本系统仅为简单示例,实际应用中需要考虑更多的安全因素,如区块链的分布式存储、共识机制等。
完整代码
# 导入 hashlib 模块,用于进行哈希运算,这里使用的是 SHA-256 哈希算法
import hashlib
# 导入 time 模块,用于获取当前时间戳
import time
# 定义 Block 类,用于表示区块链中的单个区块
class Block:
# 类的构造函数,用于初始化区块的属性
def __init__(self, index, timestamp, data, previous_hash):
# 区块在区块链中的索引,用于标识区块的位置
self.index = index
# 区块创建时的时间戳,记录区块生成的时间
self.timestamp = timestamp
# 区块中存储的数据,这里可以是文件信息、交易记录等
self.data = data
# 前一个区块的哈希值,用于将区块链接成链
self.previous_hash = previous_hash
# 当前区块的哈希值,通过调用 calculate_hash 方法计算得到
self.hash = self.calculate_hash()
# 计算当前区块哈希值的方法
def calculate_hash(self):
# 将区块的索引、时间戳、数据和前一个区块的哈希值拼接成一个字符串
block_string = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}"
# 使用 SHA-256 哈希算法对拼接后的字符串进行哈希运算
# encode() 方法将字符串转换为字节类型,hexdigest() 方法将哈希对象转换为十六进制字符串
return hashlib.sha256(block_string.encode()).hexdigest()
# 定义 Blockchain 类,用于表示整个区块链
class Blockchain:
# 类的构造函数,用于初始化区块链
def __init__(self):
# 区块链是一个列表,初始时包含一个创世区块,通过调用 create_genesis_block 方法创建
self.chain = [self.create_genesis_block()]
# 创建创世区块的方法,创世区块是区块链的第一个区块
def create_genesis_block(self):
# 创建一个索引为 0,时间为当前时间,数据为 "Genesis Block",前一个哈希值为 "0" 的区块
return Block(0, time.time(), "Genesis Block", "0")
# 获取区块链中最后一个区块的方法
def get_latest_block(self):
# 通过索引 -1 可以获取列表中的最后一个元素,即最后一个区块
return self.chain[-1]
# 向区块链中添加新区块的方法
def add_block(self, new_block):
# 将新区块的前一个哈希值设置为当前区块链中最后一个区块的哈希值
new_block.previous_hash = self.get_latest_block().hash
# 重新计算新区块的哈希值,确保哈希值的准确性
new_block.hash = new_block.calculate_hash()
# 将新区块添加到区块链列表的末尾
self.chain.append(new_block)
# 验证区块链是否有效的方法
def is_chain_valid(self):
# 从索引 1 开始遍历区块链列表,因为索引 0 是创世区块
for i in range(1, len(self.chain)):
# 获取当前遍历到的区块
current_block = self.chain[i]
# 获取当前区块的前一个区块
previous_block = self.chain[i - 1]
# 检查当前区块的哈希值是否与重新计算得到的哈希值一致
# 如果不一致,说明区块数据可能被篡改,返回 False
if current_block.hash != current_block.calculate_hash():
return False
# 检查当前区块的前一个哈希值是否与前一个区块的实际哈希值一致
# 如果不一致,说明区块链的链接可能被破坏,返回 False
if current_block.previous_hash != previous_block.hash:
return False
# 如果遍历完整个区块链都没有发现问题,返回 True,表示区块链有效
return True
# 计算指定文件哈希值的函数
def calculate_file_hash(file_path):
try:
# 创建一个 SHA-256 哈希对象
hash_object = hashlib.sha256()
# 以二进制只读模式打开指定路径的文件
with open(file_path, 'rb') as file:
# 分块读取文件内容,每次读取 4096 字节
# iter(lambda: file.read(4096), b"") 是一个迭代器,当读取到文件末尾(返回空字节串)时停止迭代
for chunk in iter(lambda: file.read(4096), b""):
# 将读取到的文件块更新到哈希对象中
hash_object.update(chunk)
# 返回文件的哈希值,以十六进制字符串的形式表示
return hash_object.hexdigest()
except FileNotFoundError:
# 如果文件不存在,打印错误信息并返回 None
print(f"文件 {file_path} 未找到。")
return None
# 创建一个 Blockchain 类的实例,用于管理区块链
blockchain = Blockchain()
# 定义第一个要比较的文件的路径
file1_path = r"D:\MyPythonProject\Deep_Learning\Blockchain\try.txt"
# 定义第二个要比较的文件的路径
file2_path = r"D:\MyPythonProject\Deep_Learning\Blockchain\try_copy.txt"
# 调用 calculate_file_hash 函数计算第一个文件的哈希值
file1_hash = calculate_file_hash(file1_path)
# 如果成功获取到第一个文件的哈希值
if file1_hash:
# 创建一个新的区块,包含第一个文件的路径和哈希值
block1 = Block(1, time.time(), f"File: {file1_path}, Hash: {file1_hash}", "")
# 将新创建的区块添加到区块链中
blockchain.add_block(block1)
# 调用 calculate_file_hash 函数计算第二个文件的哈希值
file2_hash = calculate_file_hash(file2_path)
# 如果成功获取到第二个文件的哈希值
if file2_hash:
# 创建一个新的区块,包含第二个文件的路径和哈希值
block2 = Block(2, time.time(), f"File: {file2_path}, Hash: {file2_hash}", "")
# 将新创建的区块添加到区块链中
blockchain.add_block(block2)
# 调用 is_chain_valid 方法验证区块链是否有效
if blockchain.is_chain_valid():
# 如果两个文件的哈希值相等,说明文件内容相同,未被篡改
if file1_hash == file2_hash:
print("两个文件内容一致,未被篡改。")
else:
# 如果两个文件的哈希值不相等,说明文件内容可能被修改过
print("两个文件内容不一致,可能存在篡改。")
else:
# 如果区块链验证失败,说明区块链中的数据可能存在问题
print("区块链验证失败,数据可能存在问题。")