基于Python实现的哈希算法

哈希(Hash)算法也称散列算法,是一种从任意数据内容中通过单向函数(One-way Function)创建数字“指纹”的方法,是密码学安全性的重要基石。 该算法将消息或数据压缩成摘要(Digest),使得数据量变小并将数据格式固定下来,任意长度内容的明文信息通过哈希计算后,输出的信息摘要长度都是一致的。

哈希算法及其特点:

(1)正向快速:给出明文和哈希算法,能够在有限时间和有限资源内,快速计算出任意长度明文的哈希值。

(2)雪崩效应:原始输入信息如果有任何的改变,产生的哈希值将会有很大的不同。

(3)逆向困难:给定若干哈希值,在现有计算条件下,有限时间内几乎无法逆向推出其所对应的原始明文。

(4)冲突避免:一般情况下,不同的明文,通过哈希计算后不会得到相同的散列值。

       在Python语言中生成哈希值很简单,既可通过其内置的hash()函数,也可以通过hashlib模块的MD5算法来实现。

from os import listdir
from os.path import isdir, join
from hashlib import md5
import sys

indent = 0 #缩进初始值

class Node: #定义节点类
    def add_child(self, child):
        assert isinstance(child, Node)
        is_leaf = False
        if child in self.children:
            return
        self.children.append(child)
        hashes = []
        for node in self.children:
            hashes.append(node.get_hash())
        prehash = ''.join(hashes)
        self.node_hash = md5(prehash.encode('utf-8')).hexdigest()
      
    def get_hash(self): #返回节点的哈希值
        return self.node_hash

    def generate_file_hash(self, path): #生成文件的信息摘要
        # print('{}Generating hash for {}'.format(' ' * indent * 2, path))
        file_hash = md5() #文件信息摘要

        if isdir(path):
            file_hash.update(''.encode('utf-8'))
        else:
            with open(path, 'rb') as f:
                for chunk in iter(lambda: f.read(4096), b''):
                    file_hash.update(chunk)
        return file_hash.hexdigest()

    def __str__(self):  #定义输出格式
        if isdir(self.path):            
            output = self.path  + ' (' + self.get_hash() + ')'
        else:
            output = self.path + ' (' + self.get_hash() + ')'
        child_count = 0
        for child in self.children:
            toadd = str(child)
            line_count = 0
            for line in toadd.split('\n'):
                output += '\n'
                if line_count == 0 and child_count == len(self.children) - 1:
                    output += '`-- ' + line
                elif line_count == 0 and child_count != len(self.children) - 1:
                    output += '|-- ' + line
                elif child_count != len(self.children) -1:
                    output += '|   ' + line
                else:
                    output += '    ' + line
                line_count += 1
            child_count += 1
        return output

    def __init__(self, path): #初始化
        global indent
        self.path = path
        self.children = []
        self.node_hash = self.generate_file_hash(path)
        self.is_leaf = True
        
        if not isdir(path):
            # print("{}Exiting init".format(' ' * indent * 2))
            return
        for obj in sorted(listdir(path)):
            # print("{}Adding child called {}".format(' ' * indent * 2, dir))
            indent += 1
            new_child = Node(join(path, obj))
            indent -= 1
            self.add_child(new_child)
      
if __name__ == '__main__': #主程序
    tree = None
    if len(sys.argv) < 2: #若没指定目录,则默认为程序当前目录
        tree = Node('./')
    else:
        tree = Node(sys.argv[1]) #参数1为指定目录
    print(tree) #输出带哈希值的目录树结构

运行截图如下:

猜你喜欢

转载自blog.csdn.net/qq_31391601/article/details/127271064
今日推荐