哈希表与区块链的简单介绍

什么是哈希?

简单来说,哈希就是输入任意长度的字符串都可以产生固定大小的输出。在比特币这种加密货币中,交易就是输入,然后经过哈希算法(比特币采用的是 SHA - 256),产生固定长度的输出。

下面就是使用 SHA-256 算法的例子:

SHA-256通过上面的例子可以看出,无论输入大或者小,输出都是固定256比特的长度。这一特性在处理大量数据和交易时是至关重要的。基于哈希这一特性,我们不用记输入数据是多么大,只需要记住hash值即可。在我们进一步讨论之前,我们首先需要看看哈希函数的各种属性以及它们在区块链中的实现方式。

加密哈希函数

加密哈希函数是一类特殊的哈希函数。为了让哈希函数达到密码安全,需要有以下几个特性:

确定性(Deterministic)

对于同一个输入,无论用哈希函数计算多少次,都会得到相同的结果。

快速计算

对于输入的字符串,能在合理的时间内算出哈希函数的输出,否则会影响系统的性能。

隐秘性

如果我们已知字符串 A 的哈希值是 H(A),那么我们没有可行的办法算出 A 是什么。注意,这里说的是 “不可行” 而不是 “不可能”。 比如下面的例子中,知道输出哈希值是可以算出输入的。

假如我们掷骰子🎲,输出就是骰子上数字的哈希值。那么在知道输出的哈希值情况下,我们能否知道骰子上的数字呢?因为哈希函数是具有确定性的,相同输入的哈希值一定相同,所以我们只需计算 1-6 的哈希值是什么,然后对比就能知道骰子上的数字是什么了。

当然,我们能够根据哈希值猜出骰子的数字,是因为输入值只有 6 种可能性。如果我们的输入值来自一个分散的集合,那么想要通过输出推导出输入的唯一方法可能就是“暴力破解法”了。暴力破解就是,任意选择一个输入,计算其哈希值,与现有哈希值对比是否一致,不断重复这一过程,直到找到一个输入的哈希值与现有哈希值一致。

那么暴力破解法是否可行呢?假设我们现在处理的是128位的哈希值。
最好的情况:第一次尝试就找到了答案,但这种情况可以说是几乎不可能的,比中大乐透还难。
最坏的情况:在尝试 2^128 -1 次后得到了答案,也就是试过了所有可能的输入才找到。
平均的情况: 在平均情况下,我们要尝试 2^128 / 2 = 2^127 次之后才能找到答案。2^127 = 1.7 X 10^38 , 也可以说是个天文数字了。

所以,在已知哈希值的情况下, 尽管可以通过暴力破解的方法找到输入的字符串是什么,但这会花费很长长长长长的时间,所以不用担心。

抗篡改能力

对于任意一个输入,哪怕是很小的改动,其哈希改变也会非常大。比如 “This is a test” 对应的哈希值是C7BE1ED902FB8DD4D48897C6452F5D7E509FBCDBE2808B16BCF4EDCE4C07D14E, 而 “this is a test” 对应的哈希值是 2E99758548972A8E8822AD47FA1017FF72F06F3FF6A016851F45C398732BC50C

看上面的例子,即便只改变了输入字符串第一个字母的大小写,输出hash值也是完全不同的。用前段时间比较流行的区块链撸猫游戏类比一下,“This is a test” 的哈希值对应猫可能是这样的:

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简易的区块链系统的Go语言实现示例: 首先,我们定义一个区块的结构体: ``` type Block struct { Index int Timestamp string Data string Hash string PrevHash string } ``` 其中,Index代表区块的索引,Timestamp代表区块产生的时间戳,Data是区块中存储的数据,Hash是该区块的哈希值,PrevHash是前一个区块的哈希值。 接下来,我们定义一个区块链的结构体: ``` type Blockchain struct { blocks []*Block } ``` 其中,blocks是一个Block类型的切片,用于存储整个区块链。接下来,我们实现一些区块链的基本操作: 1.创建创世区块: ``` func (bc *Blockchain) createGenesisBlock() { block := &Block{ Index: 0, Timestamp: time.Now().String(), Data: "Genesis Block", PrevHash: "", } block.Hash = calculateHash(block) bc.blocks = append(bc.blocks, block) } ``` 2.添加新的区块: ``` func (bc *Blockchain) addBlock(data string) { prevBlock := bc.blocks[len(bc.blocks)-1] newBlock := &Block{ Index: prevBlock.Index + 1, Timestamp: time.Now().String(), Data: data, PrevHash: prevBlock.Hash, } newBlock.Hash = calculateHash(newBlock) bc.blocks = append(bc.blocks, newBlock) } ``` 3.计算区块的哈希值: ``` func calculateHash(block *Block) string { record := strconv.Itoa(block.Index) + block.Timestamp + block.Data + block.PrevHash h := sha256.New() h.Write([]byte(record)) hash := h.Sum(nil) return hex.EncodeToString(hash) } ``` 最后,我们可以使用以下代码来测试我们的区块链系统: ``` func main() { bc := Blockchain{} bc.createGenesisBlock() bc.addBlock("Block 1") bc.addBlock("Block 2") for _, block := range bc.blocks { fmt.Printf("Index: %d\n", block.Index) fmt.Printf("Timestamp: %s\n", block.Timestamp) fmt.Printf("Data: %s\n", block.Data) fmt.Printf("Hash: %s\n", block.Hash) fmt.Printf("PrevHash: %s\n", block.PrevHash) fmt.Println() } } ``` 运行结果: ``` Index: 0 Timestamp: 2022-05-09 21:15:14.0970406 +0800 CST m=+0.004974101 Data: Genesis Block Hash: 5c8a5b5f29b7b0a9f4ab3d1c3f4c5b9e5a3d5f6d7cf1f51a7c9b4d5d0d2f44e4 PrevHash: Index: 1 Timestamp: 2022-05-09 21:15:14.0980389 +0800 CST m=+0.005972401 Data: Block 1 Hash: 4e59b5aae5b8d83f1c2f8ce7f6d8d9a6a2c5c34b4a37a9ea6a8178567e0e34d2 PrevHash: 5c8a5b5f29b7b0a9f4ab3d1c3f4c5b9e5a3d5f6d7cf1f51a7c9b4d5d0d2f44e4 Index: 2 Timestamp: 2022-05-09 21:15:14.0980389 +0800 CST m=+0.005972401 Data: Block 2 Hash: 73c4d5e8d166c7f4e1f1c5c50289597f7990a1cda3dd953f03d1d4400f8e71e2 PrevHash: 4e59b5aae5b8d83f1c2f8ce7f6d8d9a6a2c5c34b4a37a9ea6a8178567e0e34d2 ``` 这样,我们就实现了一个简易的区块链系统。当然,这只是一个基础的示例,实际的区块链系统要比这个复杂得多,包括更多的功能和安全性考虑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值