merkle树
莫科尔树存储哈希值
一棵莫科尔树,树中每个叶子节点对应一个哈希值。
莫科尔树的高度为 h,那么每个莫科尔树能够记录 2**h个完整性摘要值。
每更新一个叶子节点,需要更新从叶子节点到根的这一路径上所有节点的哈希值。
如图 ,节点 1 和节点 2 已经存储了完整性信息,新完整性信息将保存在节点 3,并且由于节点 3 的值发生变化,导致需要重新计算节点 6 和节点 7 的哈希值。
实现
from algorithm.g_hash import G_hash
""""
l左节点
r右节点
p父节点
hash存储的hash值,每修改一次叶子节点向上更新
data其他数据
"""
class Node:
def __init__(self):
self.l=None
self.r=None
self.p=None
self.hash="\\"
self.data="\\"
def change_data(self,data):
self.data=data
self.hash=G_hash(data)
return self.hash
"""
init初始化树
root根节点
h树的高度,0代表只有根节点
leaf空余的叶子数
add()从root向下递归添加h层高的节点
creat()创建h高的树 (根节点没算)
update() 其实是从左到右向空余叶子添加数据
up_update()向上更新节点知道父节点
show2层次遍历树,显示
show2由show_tree()调用
sum()是返回根节点的所有点个数
"""
class merkle_tree:
def __int__(self):
self.root = None
self.h=0
self.leaf=0
# 添加 h层树的节点
def add(self,item,h):
l= Node()
r=Node()
l.p=item
item.l=l
r.p=item
item.r=r
h = h - 1
if h==0:
return
else:
self.add(l,h)
self.add(r,h)
# 莫科尔树的高度为 h,那么每个莫科尔树能够记录 2h个电子
# 证据片段的完整性摘要值。
# 除了根节点需要h层
def creat(self,h):
self.root=Node()
self.h=h
self.leaf=2**h
self.add(self.root,h)
return self.root
# 从左到右添加叶子节点
def update(self,data,hash):
if self.leaf==0:
print("本树已满")
return
temp=self.root
h=self.h
leaf=self.leaf
# 对于每一个节点p,
# 如果属与它的剩余叶子节点大于一半,下一个空余叶子就在左边
# p的左节点的剩余等于 p的所剩叶子节点减去所有叶子节点的一半
# 否则就在右边
# 叶子节点个数从根节点开始每层分别是 2**(h-1)
# h=1时就是叶子节点那一层
while(h!=0):
if leaf>2**(h-1):
leaf=leaf-2**(h-1)
temp=temp.l
else:
temp=temp.r
h=h-1
self.leaf-=1
temp.data=data
temp.hash=hash
self.up_update(temp)
return temp
def up_update(self,temp):
if temp.p!=None:
temp=temp.p
temp.hash=G_hash(temp.l.hash+temp.r.hash)
self.up_update(temp)
# 左到右 遍历
def show1(self,root):
if root.l!=None:
print("向左",end="")
self.show(root.l)
print("向右", end="")
self.show(root.r)
if root.l==None:
print(root.hash)
print(root.data)
# 层次遍历
def show2(self,root):
x=[]
cc=[]
x.append(root)
print("\t",root.hash)
while x!=[]:
if x[0].l==None:
break
for _ in range(len(x)):
print("\t",'%-70s' % x[_].l.hash,end="")
print("\t",'%-70s' % x[_].r.hash,end="")
cc.append(x[_].l)
cc.append(x[_].r)
print("")
x=cc
cc=[]
def show_tree(self):
root=self.root
self.show2(root)
# 除了根节点
def sum(self,root):
if root.l!=None and root.r!=None:
return 2+self.sum(root.l)+self.sum(root.r)
if root.l==None or root.r ==None:
return 0
# test
b=merkle_tree()
b.creat(4)
print(b.sum(b.root))
b.update("1","1.hash")
b.update("2","2.hash")
b.update("3","3.hash")
b.show_tree()