Skip to content

Commit

Permalink
merkle
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuangcp committed Feb 14, 2024
1 parent 6c58858 commit 797cccb
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 8 deletions.
71 changes: 71 additions & 0 deletions algorithm/ds/tree/merkle_tree.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,76 @@
package main

import (
"crypto/md5"
"fmt"
)

// 基于二叉树实现 哈希树
// Git 用于比对文件系统差异时提升效率
// P2P下载中BT种子的构成是hash列表(按块拆分文件后做hash得到)
// https://en.wikipedia.org/wiki/Merkle_tree
// https://yeasy.gitbook.io/blockchain_guide/05_crypto/merkle_trie

type (
Merkle struct {
tree *BinTree[string]
}
)

func CreateMerkleByFile(path string) *Merkle {
// 对文件分块计算Hash构造树并存储
return nil
}

func CreateMerkle(hash []string) *Merkle {
if len(hash) == 0 {
return nil
}

var tmp []*BinTree[string]
for _, s := range hash {
tmp = append(tmp, &BinTree[string]{Data: s})
}
for {
if len(tmp) == 1 {
break
}
var par []*BinTree[string]
var node *BinTree[string]
for i := range tmp {
if node == nil {
node = &BinTree[string]{Left: tmp[i]}
par = append(par, node)
} else {
node.Right = tmp[i]
node = nil
}
}
for _, b := range par {
fillData(b)
}
tmp = par
}
return &Merkle{tree: tmp[0]}
}
func (m *Merkle) Same(merkle *Merkle) bool {
if merkle == nil {
return false
}
return m.tree.Data == merkle.tree.Data
}
func fillData(node *BinTree[string]) {
if node == nil {
return
}
c := node.Left.Data
if node.Right != nil {
c += " " + node.Right.Data
}

node.Data = hash(c)
}
func hash(val string) string {
sum := md5.Sum([]byte(val))
return fmt.Sprintf("%x", sum)
}
27 changes: 27 additions & 0 deletions algorithm/ds/tree/merkle_tree_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"github.com/kuangcp/gobase/pkg/ctool/algo"
"github.com/stretchr/testify/assert"
"testing"
)

func TestInitMerkleByHash(t *testing.T) {
merkle := CreateMerkle([]string{"a", "b", "c", "d", "e", "f"})

println(algo.PrintBiMindMap(merkle.tree))
}

func TestMerkle_Same(t *testing.T) {
a := CreateMerkle([]string{"a", "b", "c", "d", "e", "f"})
println(algo.PrintBiMindMap(a.tree))

b := CreateMerkle([]string{"a", "b", "c", "d", "e", "f"})
println(algo.PrintBiMindMap(b.tree))

c := CreateMerkle([]string{"a", "b", "c", "d", "e"})
println(algo.PrintBiMindMap(c.tree))

assert.Equal(t, a.Same(b), true)
assert.Equal(t, a.Same(c), false)
}
7 changes: 5 additions & 2 deletions algorithm/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ go 1.19

require (
github.com/kuangcp/gobase/pkg/ctool v1.1.9
github.com/tidwall/pretty v1.2.1
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
github.com/tidwall/pretty v1.2.1
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
11 changes: 11 additions & 0 deletions algorithm/gowork
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go 1.19
//
//use (
// .
// huffman
// linkedlist
//)
//
//replace (
// github.com/kuangcp/gobase/pkg/ctool v1.1.5 => ../pkg/ctool
//)
2 changes: 2 additions & 0 deletions learn/system/go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module system

// 系统级信息

go 1.20

require (
Expand Down
4 changes: 2 additions & 2 deletions pkg/ctool/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ go 1.18

require (
github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.2.1
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
go.uber.org/goleak v1.3.0
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848
)

require (
Expand Down
4 changes: 2 additions & 2 deletions pkg/ctool/stream/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ func TestToSet(t *testing.T) {
func TestJoinPerformance(t *testing.T) {
start := time.Now().UnixMicro()
_ = ToJoin(JustN(10000).MapStr())
fmt.Println(time.Now().UnixMicro()-start, "us")
fmt.Println("sin", time.Now().UnixMicro()-start, "us")

start = time.Now().UnixMicro()
_ = ToJoin(JustN(10000).Map(ToString, WithWorkers(100)))
fmt.Println(time.Now().UnixMicro()-start, "us")
fmt.Println("con", time.Now().UnixMicro()-start, "us")
}

func TestMultiGet(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion toolbox/countzh/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ go 1.13

require (
github.com/go-redis/redis/v7 v7.2.0
github.com/kuangcp/gobase/pkg/cuibase v1.0.5
github.com/kuangcp/gobase/pkg/cuibase v1.0.7
)
2 changes: 1 addition & 1 deletion toolbox/ksync/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func init() {
flag.IntVar(&port, "p", 8000, "port")
flag.IntVar(&checkSec, "c", 2, "check duration second")
flag.BoolVar(&version, "v", false, "version")
flag.StringVar(&serverAddr, "s", "", "init server host&port. ag: 192.168.0.1:8000")
flag.StringVar(&serverAddr, "s", "", "init server host and port. ag: 192.168.0.1:8000")
flag.StringVar(&localHost, "l", "", "local side host. ag: 192.168.0.2")
flag.StringVar(&syncDir, "d", "./", "sync dir.")
}
Expand Down

0 comments on commit 797cccb

Please sign in to comment.