基于Hutool的Merkle树hash值生成工具
SHAUtil工具
package com.blockchain.qgy.util;
import com.xiaoleilu.hutool.crypto.digest.DigestUtil;
import org.apache.commons.codec.binary.Hex;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
*
* 生成SHA-256的工具
*
* @author QGY
*
*/
public class SHAUtil {
/**
* function 利用apache commons-codec的工具类实现SHA-256
* @param plainText:明文
* @return 密文
*/
public static String getSHA256BasedMD(String plainText){
MessageDigest messageDigest;
String encdeStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(plainText.getBytes(StandardCharsets.UTF_8));
encdeStr = new String(Hex.encodeHex(hash));
} catch (Exception e){
e.printStackTrace();
}
return encdeStr;
}
/**
* function 利用Hutool工具类实现SHa-256加密
* @param plainText:明文
* @return 密文
*/
public static String sha256BasedHutool(String plainText){
return DigestUtil.sha256Hex(plainText);
}
}
Merkle树hash值生成工具
package com.blockchain.qgy.util;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
* merkle树的对应工具
*
* @author QGY
*
*/
public class MerkleTreeUtil {
/**
* function 获取根节点的hash值
* @param hashList:非根节点的hash值的树状数组
* @return 根节点的hash值
*/
public static String getTreeNodeHash(List<String> hashList){
//判断入参
if(Objects.isNull(hashList) || hashList.size() == 0) return null;
while (hashList.size() != 1) {
hashList = getMerkleNodeList(hashList);
}
//找出根节点
return hashList.get(0);
}
/**
* function 根据非根节点将叶子节点的hash值处理成其父亲节点的hash值
* @param hashList:非根节点的hash值的树状数组
* @return 非根节点的hash值集合(处理后)
*/
private static List<String> getMerkleNodeList(List<String> hashList) {
//判断入参
if(Objects.isNull(hashList) || hashList.size() == 0) return hashList;
List<String> merkleNodeList = new ArrayList<>();
int index = 0;
int length = hashList.size();
//处理hash值树状数组
while (index < length) {
//1.获取左孩子节点的hash值
String left = hashList.get(index++);
//2.获取右孩子节点的hash值
String right = "";
if (index < length) {
right = hashList.get(index++);
}
//计算左右孩子节点的父亲节点的hash值
String currHash = SHAUtil.sha256BasedHutool(left.concat(right));
merkleNodeList.add(currHash);
}
return merkleNodeList;
}
}
对Merkle树的简单说明
Merkle树是一种数据结构,它是一种哈希树的变体。它由计算机科学家Ralph Merkle在1979年提出。Merkle树的主要目的是验证大量数据的完整性。
Merkle树的构建过程是通过对原始数据块逐层进行哈希计算来完成的。首先,原始数据被分成固定大小的块。然后,每个块都通过一个哈希函数计算出一个固定长度的哈希值。这些哈希值再通过哈希函数再次计算,直到最后只剩下一个哈希值,这个哈希值被称为根哈希。根哈希是Merkle树的根节点。
Merkle树的特点是它的任何部分数据的一点改变都会导致整个树的根哈希值发生变化。这使得Merkle树非常适合于验证大量数据的完整性。通过比较根哈希值和任意子节点的哈希值,可以快速确定数据是否被篡改。
Merkle树在许多领域得到了广泛应用,特别是在密码学和区块链中。在密码学中,Merkle树用于验证数字证书的完整性。在区块链中,Merkle树用于验证交易的有效性,以及验证区块的完整性。通过使用Merkle树,可以提高数据的安全性和可靠性。
依赖坐标
<dependency> <groupId>com.xiaoleilu</groupId> <artifactId>hutool-all</artifactId> <version>3.0.9</version> </dependency>