Java手写简单Merkle树

embedded/2025/2/3 8:26:21/

 Java手写Merkle树代码

java">package com.blockchain.qgy.component;import com.blockchain.qgy.model.MerkleTreeNode;
import com.blockchain.qgy.util.SHAUtil;import java.util.*;public class MerkleTree<T> {//merkle树private List<MerkleTreeNode<T>> list;//根节点private MerkleTreeNode<T> root;public MerkleTree(List<T> nodes){createMerkleTree(nodes);}/*** function 初始化merkle树* @param nodes: 数据集合*/private void createMerkleTree(List<T> nodes) {//判断入参if (Objects.isNull(nodes) || nodes.size() == 0) return;list = new ArrayList<>();//创建叶子节点List<MerkleTreeNode<T>> leafList = createLeafList(nodes);list.addAll(leafList);//创建父级节点List<MerkleTreeNode<T>> parents = new ArrayList<>(leafList);//循环创建直到找到根节点do {List<MerkleTreeNode<T>> temp = new ArrayList<>(parents);temp = createParentList(temp);parents = temp;list.addAll(parents);}while (parents.size() > 1);root = parents.get(0);}/*** function 初始化父亲节点* @param leafList:叶子节点* @return 父节点*/private List<MerkleTreeNode<T>> createParentList(List<MerkleTreeNode<T>> leafList) {//判断入参if (Objects.isNull(leafList) || leafList.size() == 0) return new ArrayList<>();List<MerkleTreeNode<T>> parents = new ArrayList<>();int length = leafList.size();for(int i = 0;i < length - 1; i += 2){MerkleTreeNode<T> parent = createParentNode(leafList.get(i),leafList.get(i+1));parents.add(parent);}//当节点数为奇数时,单独进行处理if ((length & 1) == 1) {MerkleTreeNode<T> parent = createParentNode(leafList.get(length - 1),null);parents.add(parent);}return parents;}/*** function 生成一个父节点* @param left:左节点* @param right:右节点* @return 父节点*/private MerkleTreeNode<T> createParentNode(MerkleTreeNode<T> left, MerkleTreeNode<T> right) {MerkleTreeNode<T> parent = new MerkleTreeNode<>();parent.setLeft(left);parent.setRight(right);String hash = left.getHash();if(!Objects.isNull(parent.getRight())) {hash = SHAUtil.sha256BasedHutool(hash.concat(parent.getRight().getHash()));}parent.setHash(hash);parent.setName("无人签名");parent.setData((T) new Object());return parent;}/*** function 初始化叶子节点* @param nodes:数据集合* @return merkle的叶子节点*/private List<MerkleTreeNode<T>> createLeafList(List<T> nodes) {//判断入参if (Objects.isNull(nodes) || nodes.size() == 0) return new ArrayList<>();List<MerkleTreeNode<T>> leafList = new ArrayList<>();for(T curr : nodes) {MerkleTreeNode<T> node = new MerkleTreeNode<>(curr);leafList.add(node);}return leafList;}public void printfTree() {Collections.reverse(list);MerkleTreeNode<T> root = list.get(0);Queue<MerkleTreeNode<T>> queue = new LinkedList<MerkleTreeNode<T>>(){{offer(root);}};printfTree(queue,1);}public void printfTree(Queue<MerkleTreeNode<T>> queue,Integer floor) {Queue<MerkleTreeNode<T>> currQueue = new LinkedList<>();System.out.println("第"+floor+"层--------------------------------------------------------------------------------------------------------------------------");while (!queue.isEmpty()) {MerkleTreeNode<T> poll = queue.poll();System.out.println(poll.toString());if(!Objects.isNull(poll.getLeft())) currQueue.offer(poll.getLeft());if(!Objects.isNull(poll.getRight())) currQueue.offer(poll.getRight());}if (!currQueue.isEmpty()) printfTree(currQueue,floor+1);}public List<MerkleTreeNode<T>> getList() {return list;}public MerkleTreeNode<T> getRoot() {return root;}public void setList(List<MerkleTreeNode<T>> list) {this.list = list;}public void setRoot(MerkleTreeNode<T> root) {this.root = root;}}

java">package com.blockchain.qgy.model;import com.blockchain.qgy.util.SHAUtil;public class MerkleTreeNode<T> {//左节点private MerkleTreeNode<T> left;//右节点private MerkleTreeNode<T> right;//区块数据private T data;//节点hash值private String hash;//数字签名private String name;public MerkleTreeNode() {}public MerkleTreeNode(T data) {this.data = data;this.hash = SHAUtil.sha256BasedHutool(data.toString());this.name = "无人签名";}public MerkleTreeNode(T data, String name){this.data = data;this.hash = SHAUtil.sha256BasedHutool(data.toString());this.name = name;}public MerkleTreeNode<T> getLeft() {return left;}public void setLeft(MerkleTreeNode<T> left) {this.left = left;}public MerkleTreeNode<T> getRight() {return right;}public void setRight(MerkleTreeNode<T> right) {this.right = right;}public T getData() {return data;}public void setData(T data) {this.data = data;}public String getHash() {return hash;}public void setHash(String hash) {this.hash = hash;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return  "MerkleTreeNode:\n" +"name:" + name + ";\n" +"data:" + data + ";\n" +"------------\n";}
}

 

注意:这里用了SHAUtil工具类,该部分代码链接如下:

SHAUtil代码

测试代码

java">package com.blockchain.qgy.test;import com.blockchain.qgy.component.MerkleTree;
import com.blockchain.qgy.model.MerkleTreeNode;
import org.testng.annotations.Test;import java.util.Arrays;
import java.util.List;public class MerkleTreeTest {@Testpublic void Test(){List<String> contents = Arrays.asList("星","极","天","下","第","一");MerkleTree<String> stringMerkleTree = new MerkleTree<>(contents);stringMerkleTree.printfTree();MerkleTreeNode<String> root = stringMerkleTree.getRoot();System.out.println("root:"+root);System.out.println("hash:"+root.getHash());}
}

结果:

"C:\Program Files\Java\jdk1.8.0_261\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\idea\IntelliJ IDEA 2020.2.1\lib\idea_rt.jar=55223:D:\idea\IntelliJ IDEA 2020.2.1\bin" -Dfile.encoding=UTF-8 -classpath "D:\idea\IntelliJ IDEA 2020.2.1\lib\idea_rt.jar;D:\idea\IntelliJ IDEA 2020.2.1\plugins\testng\lib\testng-rt.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_261\jre\lib\rt.jar;D:\项目\区块链\target\classes;C:\Users\86153\Desktop\java架包\org\testng\testng\6.8.7\testng-6.8.7.jar;C:\Users\86153\Desktop\java架包\junit\junit\4.10\junit-4.10.jar;C:\Users\86153\Desktop\java架包\org\hamcrest\hamcrest-core\1.1\hamcrest-core-1.1.jar;C:\Users\86153\Desktop\java架包\org\beanshell\bsh\2.0b4\bsh-2.0b4.jar;C:\Users\86153\Desktop\java架包\com\beust\jcommander\1.27\jcommander-1.27.jar;C:\Users\86153\Desktop\java架包\org\yaml\snakeyaml\1.12\snakeyaml-1.12.jar;C:\Users\86153\Desktop\java架包\org\mockito\mockito-all\1.9.5\mockito-all-1.9.5.jar;C:\Users\86153\Desktop\java架包\com\xiaoleilu\hutool-all\3.0.9\hutool-all-3.0.9.jar;C:\Users\86153\Desktop\java架包\com\google\crypto\tink\tink\1.2.0\tink-1.2.0.jar;C:\Users\86153\Desktop\java架包\com\amazonaws\aws-java-sdk-core\1.11.166\aws-java-sdk-core-1.11.166.jar;C:\Users\86153\Desktop\java架包\software\amazon\ion\ion-java\1.0.2\ion-java-1.0.2.jar;C:\Users\86153\Desktop\java架包\com\fasterxml\jackson\dataformat\jackson-dataformat-cbor\2.6.7\jackson-dataformat-cbor-2.6.7.jar;C:\Users\86153\Desktop\java架包\joda-time\joda-time\2.8.1\joda-time-2.8.1.jar;C:\Users\86153\Desktop\java架包\com\amazonaws\aws-java-sdk-kms\1.11.166\aws-java-sdk-kms-1.11.166.jar;C:\Users\86153\Desktop\java架包\com\amazonaws\jmespath-java\1.11.166\jmespath-java-1.11.166.jar;C:\Users\86153\Desktop\java架包\com\fasterxml\jackson\core\jackson-databind\2.6.7.1\jackson-databind-2.6.7.1.jar;C:\Users\86153\Desktop\java架包\com\fasterxml\jackson\core\jackson-annotations\2.6.0\jackson-annotations-2.6.0.jar;C:\Users\86153\Desktop\java架包\com\google\api-client\google-api-client\1.22.0\google-api-client-1.22.0.jar;C:\Users\86153\Desktop\java架包\com\google\oauth-client\google-oauth-client\1.22.0\google-oauth-client-1.22.0.jar;C:\Users\86153\Desktop\java架包\com\google\http-client\google-http-client\1.22.0\google-http-client-1.22.0.jar;C:\Users\86153\Desktop\java架包\org\apache\httpcomponents\httpclient\4.0.1\httpclient-4.0.1.jar;C:\Users\86153\Desktop\java架包\org\apache\httpcomponents\httpcore\4.0.1\httpcore-4.0.1.jar;C:\Users\86153\Desktop\java架包\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar;C:\Users\86153\Desktop\java架包\commons-codec\commons-codec\1.3\commons-codec-1.3.jar;C:\Users\86153\Desktop\java架包\com\google\http-client\google-http-client-jackson2\1.22.0\google-http-client-jackson2-1.22.0.jar;C:\Users\86153\Desktop\java架包\com\fasterxml\jackson\core\jackson-core\2.1.3\jackson-core-2.1.3.jar;C:\Users\86153\Desktop\java架包\com\google\apis\google-api-services-cloudkms\v1-rev9-1.22.0\google-api-services-cloudkms-v1-rev9-1.22.0.jar;C:\Users\86153\Desktop\java架包\com\google\guava\guava\25.0-jre\guava-25.0-jre.jar;C:\Users\86153\Desktop\java架包\com\google\code\findbugs\jsr305\1.3.9\jsr305-1.3.9.jar;C:\Users\86153\Desktop\java架包\org\checkerframework\checker-compat-qual\2.0.0\checker-compat-qual-2.0.0.jar;C:\Users\86153\Desktop\java架包\com\google\errorprone\error_prone_annotations\2.1.3\error_prone_annotations-2.1.3.jar;C:\Users\86153\Desktop\java架包\com\google\j2objc\j2objc-annotations\1.1\j2objc-annotations-1.1.jar;C:\Users\86153\Desktop\java架包\org\codehaus\mojo\animal-sniffer-annotations\1.14\animal-sniffer-annotations-1.14.jar;C:\Users\86153\Desktop\java架包\com\google\auto\service\auto-service\1.0-rc4\auto-service-1.0-rc4.jar;C:\Users\86153\Desktop\java架包\com\google\auto\auto-common\0.8\auto-common-0.8.jar;C:\Users\86153\Desktop\java架包\com\google\protobuf\protobuf-java\3.3.0\protobuf-java-3.3.0.jar;C:\Users\86153\Desktop\java架包\org\json\json\20170516\json-20170516.jar;D:\idea\IntelliJ IDEA 2020.2.1\plugins\testng\lib\jcommander-1.27.jar" com.intellij.rt.testng.RemoteTestNGStarter -usedefaultlisteners false -socket55222 @w@C:\Users\86153\AppData\Local\Temp\idea_working_dirs_testng.tmp -temp C:\Users\86153\AppData\Local\Temp\idea_testng.tmp
[TestNG] Running:
  C:\Users\86153\AppData\Local\JetBrains\IntelliJIdea2020.2\temp-testng-customsuite.xml


第1层------------------------------------------------------------------------------------------------------------------
MerkleTreeNode:
name:无人签名;
data:java.lang.Object@b684286;
------------

第2层------------------------------------------------------------------------------------------------------------------
MerkleTreeNode:
name:无人签名;
data:java.lang.Object@880ec60;
------------

MerkleTreeNode:
name:无人签名;
data:java.lang.Object@3f3afe78;
------------

第3层------------------------------------------------------------------------------------------------------------------
MerkleTreeNode:
name:无人签名;
data:java.lang.Object@7f63425a;
------------

MerkleTreeNode:
name:无人签名;
data:java.lang.Object@36d64342;
------------

MerkleTreeNode:
name:无人签名;
data:java.lang.Object@39ba5a14;
------------

第4层------------------------------------------------------------------------------------------------------------------
MerkleTreeNode:
name:无人签名;
data:星;
------------

MerkleTreeNode:
name:无人签名;
data:极;
------------

MerkleTreeNode:
name:无人签名;
data:天;
------------

MerkleTreeNode:
name:无人签名;
data:下;
------------

MerkleTreeNode:
name:无人签名;
data:第;
------------

MerkleTreeNode:
name:无人签名;
data:一;
------------

root:MerkleTreeNode:
name:无人签名;
data:java.lang.Object@b684286;
------------

hash:4e8da83f3ee3cb2ddb2d5dec5724a0c01bb4f6f48d2f7c3dd46f51158b26b5f4


===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================


Process finished with exit code 0
 


http://www.ppmy.cn/embedded/159136.html

相关文章

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(四)

Understanding Diffusion Models: A Unified Perspective&#xff08;四&#xff09; 文章概括学习扩散噪声参数&#xff08;Learning Diffusion Noise Parameters&#xff09;三种等效的解释&#xff08;Three Equivalent Interpretations&#xff09; 文章概括 引用&#xf…

曲线救国——uniapp封装toast消息提示组件(js)

说明:本组件借用到uv-ui前端框架的<uv-toast ref="toast"></uv-toast>作为消息提示,有条件的可以自己设计。另外主要用到@uni-ku/root@1.1.0。 目录结构(主要文件): 安装@uni-ku/root@1.1.0 npm install -D @uni-ku/rootvite.config.js: import {d…

8.5 Whisper:解锁语音识别新高度的智能助手

Whisper:解锁语音识别新高度的智能助手 引言:从语音到文字的技术飞跃 在当今的人工智能技术中,语音识别 已成为人机交互的重要环节。从语音助手到实时字幕生成,语音识别技术正在改变我们的沟通方式。OpenAI Whisper 是一款功能强大的开源语音识别模型,它结合了高精度、语…

前端知识速记--HTML篇:src和href

前端知识速记–HTML篇&#xff1a;src和href 一、属性概述 1.1 src属性 src&#xff08;source的缩写&#xff09;属性用于指定外部资源的来源&#xff0c;通常用于嵌入媒体内容或脚本文件。它告知浏览器去哪个地址加载相应的资源。使用src时&#xff0c;浏览器在解析到该元…

手机Python爬虫教程:利用手机学习Python爬虫的终极指南_python可以在手机上写爬虫吗

利用手机进行学习&#xff0c;你可以充分利用碎片化的时间段进行学习。无论是在公交车上还是等待朋友的时候&#xff0c;你都可以打开手机学习Python爬虫知识&#xff0c;提高学习效率。 1.1 灵活安排学习任务 在利用碎片化时间学习时&#xff0c;你可以根据自己的学习进度和…

【linux】linux缺少tar命令/-bash: tar:未找到命令

问题&#xff1a; -bash: tar&#xff1a;未找到命令 原因 这错误信息"-bash: tar:未找到命令"表示系统无法找到tar命令。tar命令是一个Linux/Unix系统下的打包压缩工具&#xff0c;它用于将多个文件合并为一个文件。如果系统报错找不到tar命令&#xff0c;可能是…

网络攻防实战指北专栏讲解大纲与网络安全法

专栏 本专栏为网络攻防实战指北&#xff0c;大纲如下所示 进度&#xff1a;目前已更完准备篇、HTML基础 计划&#xff1a;所谓基础不牢&#xff0c;地动山摇。所以下一步将持续更新基础篇内容 讲解信息安全时&#xff0c;结合《中华人民共和国网络安全法》&#xff08;以下简…

首发!ZStack 智塔支持 DeepSeek V3/R1/ Janus Pro,多种国产 CPU/GPU 可私有化部署

2025年2月2日&#xff0c;针对日益强劲的AI推理需求和企业级AI应用私有化部署场景&#xff08;Private AI&#xff09;&#xff0c;云轴科技 ZStack 宣布 AI Infra 平台 ZStack 智塔全面支持企业私有化部署 DeepSeek V3/R1/ Janus Pro三种模型&#xff0c;并可基于海光、昇腾、…