Java手写简单Merkle树

 Java手写Merkle树代码

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;}}

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代码

测试代码

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.mzph.cn/news/894224.shtml

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

相关文章

蓝桥杯真题k倍区间

题目如下 代码解析&#xff1a; 成功AC

python项目之requirements.txt文件

Python项目中可以包含一个 requirements.txt 文件&#xff0c;用于记录所有依赖包及其精确的版本号用以新环境部署。 当我们开发新项目的时候&#xff0c;会用virtualenv创建很多python独立环境&#xff0c;这时候就会出现在不同环境下安装相同的模块的情况&#xff0c;这时候…

算法题(53):对称二叉树

审题&#xff1a; 需要我们判断二叉树是否满足对称结构&#xff0c;并返回判断结果 思路&#xff1a; 方法一&#xff1a;递归 其实是否对称分成两部分判断 第一部分&#xff1a;根节点是否相等 第二部分&#xff1a;根节点一的左子树和根节点二的右子树是否相等&#xff0c;根…

使用 cmake

使用前注意 : CMake是一种跨平台的构建系统&#xff0c;它用于管理软件构建过程&#xff0c;尤其适合多语言、多配置的项目。CMake不直接构建软件&#xff0c;而是生成特定构建工具&#xff08;如Makefile或Visual Studio项目&#xff09;所需的配置文件。 如果仅仅使用 qt 编…

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先&#xff0c;要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理&#xff0c;还是其他功能&#xff1f;明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时&#xff0c;你需要选择适合的编程语言、…

学习数据结构(5)单向链表的实现

&#xff08;1&#xff09;头部插入 &#xff08;2&#xff09;尾部删除 &#xff08;3&#xff09;头部删除 &#xff08;4&#xff09;查找 &#xff08;5&#xff09;在指定位置之前插入节点 &#xff08;6&#xff09;在指定位置之后插入节点 &#xff08;7&#xff09;删除…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构&#xff0c;通过 Key 可以快速查找到对应的 Value。B 树索引由根页面&#xff08;Root&am…

Vue-cli 脚手架搭建

安装node.js 官网下载node.js安装包&#xff0c;地址&#xff1a;Node.js — Download Node.js 先在node.js即将要安装的路径下创建两个文件夹&#xff1a;node_cache&#xff08;缓存&#xff09;、node_global&#xff08;全局&#xff09; 点击安装包&#xf…

深度解析 DeepSeek R1:强化学习与知识蒸馏的协同力量

DeepSeek-R1 的问世&#xff0c;无疑在 AI 领域激起了千层浪。自发布仅一周&#xff0c;它便凭借卓越的性能和创新的技术&#xff0c;成为 AI 社区热议的焦点&#xff0c;代表着人工智能在推理和理解能力上的重大飞跃。今天我们一起深度解析一下DeepSeek-R1 一、强大基石&…

openssl 生成证书 windows导入证书

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

笔记本搭配显示器

笔记本&#xff1a;2022款拯救者Y9000P&#xff0c;显卡RTX3060&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz&#xff0c;无DP1.4口 显示器&#xff1a;2024款R27Q&#xff0c;27存&#xff0c;分辨率2560*1600&#xff0c;刷新率&#xff1a;165Hz &…

在php中怎么打开OpenSSL

&#xff08;点击即可进入聊天助手&#xff09; 背景 在使用php做一些项目时,有用到用户邮箱注册等,需要开启openssl的能力 在php系统中openssl默认是关闭状态的,在一些低版本php系统中,有的甚至需要在服务器终端后台,手动安装 要打开OpenSSL扩展&#xff0c;需要进行以下步骤 …

【单细胞第二节:单细胞示例数据分析-GSE218208】

GSE218208 1.创建Seurat对象 #untar(“GSE218208_RAW.tar”) rm(list ls()) a data.table::fread("GSM6736629_10x-PBMC-1_ds0.1974_CountMatrix.tsv.gz",data.table F) a[1:4,1:4] library(tidyverse) a$alias:gene str_split(a$alias:gene,":",si…

K8S 快速实战

K8S 核心架构原理: 我们已经知道了 K8S 的核心功能:自动化运维管理多个容器化程序。那么 K8S 怎么做到的呢?这里,我们从宏观架构上来学习 K8S 的设计思想。首先看下图: K8S 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责核心的调度、管理和运维,Slave…

134.力扣刷题--加油站--滑动窗口

你知道的&#xff0c;失败总是贯穿人生的始终。 加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#x…

爬虫基础(二)Web网页的基本原理

一、网页的组成 网页由三部分构成&#xff1a;HTML、JavaScript、CSS。 &#xff08;1&#xff09;HTML HTML 相当于网页的骨架&#xff0c;它通过使用标签来定义网页内容的结构。 举个例子&#xff1a; 它把图片标签为img、把视频标签为video&#xff0c;然后组合到一个界面…

Three.js实现3D动态心形与粒子背景的数学与代码映射解析

一、效果概述 本文通过Three.js构建了一个具有科技感的3D场景&#xff0c;主要包含两大视觉元素&#xff1a; 动态心形模型&#xff1a;采用数学函数生成基础形状&#xff0c;通过顶点操作实现表面弧度。星空粒子背景&#xff1a;随机分布的粒子群组形成空间层次感。复合动画…

Java线程认识和Object的一些方法

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 要对Java线程有整体了解&#xff0c;深入认识到里面的一些方法和Object对象方法的区别。认识到Java对象的ObjectMonitor&#xff0c;这有助于后面的Synchron…

【蓝桥杯省赛真题02】C++猫吃鱼 第十届蓝桥杯青少年创意编程大赛 算法思维 C++编程省赛真题解

目录 C猫吃鱼 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、运行结果 五、考点分析 七、推荐资料 C猫吃鱼 第十届蓝桥杯青少年创意编程大赛C选拔赛真题 一、题目要求 明明家从1号站点出发&#xff0c;开车去旅游&#xff0c;一共要经过n个…

无公网IP 外网访问 本地部署夫人 hello-algo

hello-algo 是一个为帮助编程爱好者系统地学习数据结构和算法的开源项目。这款项目通过多种创新的方式&#xff0c;为学习者提供了一个直观、互动的学习平台。 本文将详细的介绍如何利用 Docker 在本地安装部署 hello-algo&#xff0c;并结合路由侠内网穿透实现外网访问本地部署…