- 下面是获得sha256加密后的64位16进制哈希值的类及方法,这里需要先导入一个通用的编码解码包commons-codec依赖,并下载好该资源。
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.binary.Hex;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @Auther:刘兰斌
* @Date: 2021/05/31/9:07
* @Explain:
*/
public class GetSHA256Str {
public static void main(String[] args) {
String t = "luotuo1";//刘兰斌
String s = getsha256str(t);
System.out.println(s);
}
public static String getsha256str(String string){
String encoderes="";
try {//初始化
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] hash = messageDigest.digest(string.getBytes(StandardCharsets.UTF_8));
encoderes = Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return encoderes;
}
}
- 借助单链表的数据结构实现,也可以借助数组集合实现
/**
* @Auther:刘兰斌
* @Date: 2021/05/31/20:33
* @Explain:
*/
public class Blocks {
private String data;
private String prehash;
private String curhash;
private Blocks next;
private int nonce;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getPrehash() {
return prehash;
}
public void setPrehash(String prehash) {
this.prehash = prehash;
}
public String getCurhash() {
return curhash;
}
public void setCurhash(String curhash) {
this.curhash = curhash;
}
public Blocks getNext() {
return next;
}
public void setNext(Blocks next) {
this.next = next;
}
public Blocks(String data, String prehash, String curhash, Blocks next) {
this.data = data;
this.prehash = prehash;
this.curhash = computerHash();
this.next = next;
this.nonce=1;
}
public String computerHash(){
return GetSHA256Str.getsha256str(this.data+this.prehash+this.nonce);
}
//获取难度值
public String getDificult(int dificulnum){
String res="";
for (int i=0;i<dificulnum;i++){
res+="0";
}
return res;
}
//开始挖矿
public void mine(int dificulnum){
while(true){
this.curhash=this.computerHash();
if (!this.curhash.substring(0,dificulnum).equals(this.getDificult(dificulnum))){
nonce++;
this.curhash=this.computerHash();
}else {
break;
}
}
System.out.println("挖矿结束!"+this.curhash);
}
@Override
public String toString() {
return "Blocks{" +
"data='" + data + '\'' +
", prehash='" + prehash + '\'' +
", curhash='" + curhash + '\'' +
", next=" + next +
'}';
}
public static void main(String[] args) {
Blocks block1 = new Blocks("转账十元","其实我是十元","",null);//这里的前一个区块的hash值实际上是模拟
Blocks block2 = new Blocks("转账二十元","其实我是二十元","",null);//这里简化只是用来计算curhash
// System.out.println(block1);
SingleLinkList singleLinkList = new SingleLinkList();
singleLinkList.addNode(block1);
singleLinkList.addNode(block2);
// System.out.println(singleLinkList);
// singleLinkList.getAncestor().getNext().setData("转账1000元!");
// singleLinkList.getAncestor().getNext().setCurhash(
// singleLinkList.getAncestor().getNext().computerHash());
//
// boolean validate = singleLinkList.isValidate();//data = "转账1000";
// System.out.println(validate);
}
}
class SingleLinkList{
//初始化第一个结点
private Blocks ancestor;
//引入工作量证明机制
private int dificultnum;
public Blocks getAncestor() {
return ancestor;
}
public void setAncestor(Blocks ancestor) {
this.ancestor = ancestor;
}
public SingleLinkList() {
this.ancestor = new Blocks("祖先节点","","",null);
this.dificultnum = 5;
}
@Override
public String toString() {
return "SingleLinkList{" +
"ancestor=" + ancestor +
'}';
}
//添加节点到区块链上中
public void addNode(Blocks blocks){
//找到上一个区块的hash值作为添加区块的前一个哈希值
Blocks temp = ancestor;
while(true){
if(temp.getNext()==null){
break;
}
temp = temp.getNext();
}
temp.setNext(blocks);
blocks.setPrehash(temp.getCurhash());
// blocks.setCurhash(blocks.computerHash());
blocks.mine(dificultnum);
blocks.setNext(null);
}
// 验证数据合法性
//验证数据是否合法
//验证hash是否正确
public boolean isValidate() {
//如果为初始化链,肯定合法
if (ancestor.getNext()==null) {//chain.size() == 1
// if(chain.get(0).getOwnhash() != chain.get(0).computerhash()){
if (!ancestor.getCurhash().equals(ancestor.computerHash())) {
//!chain.get(0).getOwnhash().equals(chain.get(0).computerhash())
return false;
}
return true;
}
//验证完第一个数据后,开始验证后面的数据
while(ancestor.getNext() != null){
Blocks nextblocks = ancestor.getNext();
if (!nextblocks.getCurhash().equals(nextblocks.computerHash())) {
System.out.println("数据发生篡改!");
return false;
}
//验证此区块的的前哈希值是否等于前一个区块的哈希值
Blocks preblocks = ancestor;
if (!nextblocks.getPrehash().equals(preblocks.getCurhash())) {
System.out.println("失败,前后数据块断裂!");
return false;
}
ancestor=ancestor.getNext();
}
return true;
}
}
- 附带数组集合实现的部分代码(未引入工作量证明机制)
import java.util.ArrayList;
/**
* @Auther:刘兰斌
* @Date: 2021/05/31/9:30
* @Explain:
*/
public class Block {
private String data;
private String prehash;
private String ownhash;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getPrehash() {
return prehash;
}
public void setPrehash(String prehash) {
this.prehash = prehash;
}
public String getOwnhash() {
return ownhash;
}
public void setOwnhash(String ownhash) {
this.ownhash = ownhash;
}
public Block(String data, String prehash, String ownhash) {
this.data = data;
this.prehash = prehash;
this.ownhash = computerhash();
}
public String computerhash() {
return GetSHA256Str.getsha256str(this.data + this.prehash);
}
@Override
public String toString() {
return "Block{" +
"data='" + data + '\'' +
", prehash='" + prehash + '\'' +
", ownhash='" + ownhash + '\'' +
'}';
}
public static void main(String[] args) {
Chain chain = new Chain();
Block Block = new Block("转账十元", "123", "");
Block block2 = new Block("转账5元", "", "");
chain.addBlocktochain(Block);
chain.addBlocktochain(block2);
System.out.println(chain);
//尝试篡改数据
chain.chain.get(1).data = "转账1000";
//尝试篡改前后的hash值
chain.chain.get(1).setOwnhash(chain.chain.get(1).computerhash());
boolean res = chain.isValidate();
System.out.println(res);
}
}
class Chain {
// Block generater = new Block("祖先节点", "", "");//祖先区块
ArrayList<Block> chain = new ArrayList<>();
public Chain() {
chain.add(new Block("祖先节点", "", ""));
}
@Override
public String toString() {
return "Chain{" +
"generater=" + new Block("祖先节点", "", "") +
", chain=" + chain +
'}';
}
//添加一个区块到链上
public ArrayList<Block> addBlocktochain(Block block) {
//找到上一个区块的hash
String lasthash = chain.get(chain.size() - 1).getOwnhash();
block.setPrehash(lasthash);
block.setOwnhash(block.computerhash());
chain.add(block);
return chain;
}
//验证数据是否合法
//验证hash是否正确
public boolean isValidate() {
//如果为初始化链,肯定合法
if (chain.size() == 1) {
// if(chain.get(0).getOwnhash() != chain.get(0).computerhash()){
if (!chain.get(0).getOwnhash().equals(chain.get(0).computerhash())) {
return false;
}
return true;
}
//验证完第一个数据后,开始验证后面的数据
for (int i = 1; i < chain.size(); i++) {
Block block = chain.get(i);
if (!block.getOwnhash().equals(block.computerhash())) {
System.out.println("数据发生篡改!");
return false;
}
//验证此区块的的前哈希值是否等于前一个区块的哈希值
Block preblock = chain.get(i - 1);
if (!block.getPrehash().equals(preblock.getOwnhash())) {
System.out.println("失败,前后数据块断裂!");
return false;
}
}
return true;
}
}
参考资源
https://www.bilibili.com/video/BV1CJ411e79V/?spm_id_from=333.788.recommend_more_video.0
https://www.bilibili.com/video/BV1JJ411477R