github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/bmt/bmt_r.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:47</date> 10 //</624342670575144960> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 // 29 // 30 // 31 // 32 // 33 // 34 // 35 // 36 // 37 package bmt 38 39 import ( 40 "hash" 41 ) 42 43 // 44 type RefHasher struct { 45 maxDataLength int // 46 sectionLength int // 47 hasher hash.Hash // 48 } 49 50 // 51 func NewRefHasher(hasher BaseHasherFunc, count int) *RefHasher { 52 h := hasher() 53 hashsize := h.Size() 54 c := 2 55 for ; c < count; c *= 2 { 56 } 57 return &RefHasher{ 58 sectionLength: 2 * hashsize, 59 maxDataLength: c * hashsize, 60 hasher: h, 61 } 62 } 63 64 // 65 // 66 func (rh *RefHasher) Hash(data []byte) []byte { 67 // 68 d := make([]byte, rh.maxDataLength) 69 length := len(data) 70 if length > rh.maxDataLength { 71 length = rh.maxDataLength 72 } 73 copy(d, data[:length]) 74 return rh.hash(d, rh.maxDataLength) 75 } 76 77 // 78 // 79 // 80 // 81 func (rh *RefHasher) hash(data []byte, length int) []byte { 82 var section []byte 83 if length == rh.sectionLength { 84 // 85 section = data 86 } else { 87 // 88 // 89 length /= 2 90 section = append(rh.hash(data[:length], length), rh.hash(data[length:], length)...) 91 } 92 rh.hasher.Reset() 93 rh.hasher.Write(section) 94 return rh.hasher.Sum(nil) 95 } 96