github.com/annchain/OG@v0.0.9/common/hash.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package common 18 19 import ( 20 "crypto/sha256" 21 "fmt" 22 "github.com/annchain/OG/arefactor/common/utilfuncs" 23 "github.com/annchain/OG/common/math" 24 "math/big" 25 "math/rand" 26 "reflect" 27 28 "bytes" 29 "strings" 30 31 "github.com/annchain/OG/common/hexutil" 32 ) 33 34 //go:generate msgp 35 36 // Length of hash in bytes. 37 const ( 38 HashLength = 32 39 ) 40 41 var ( 42 hashT = reflect.TypeOf(Hash{}) 43 ) 44 45 type Padding uint 46 47 const ( 48 PaddingLeft Padding = iota 49 PaddingRight 50 PaddingNone 51 ) 52 53 // Hash represents the 32 byte of Hash. 54 //msgp:tuple Hash 55 type Hash struct { 56 Bytes [HashLength]byte `msgp:"bytes"` 57 } 58 59 //msgp:tuple Hashes 60 type Hashes []Hash 61 62 type HashBytes [HashLength]byte 63 64 func (h *Hash) Empty() bool { 65 var hs Hash 66 return bytes.Equal(h.Bytes[:], hs.Bytes[:]) 67 } 68 69 // BytesToHash sets b to hash. 70 // If b is larger than len(h), b will be cropped from the left. 71 func BytesToHash(b []byte) Hash { 72 var h Hash 73 h.MustSetBytes(b, PaddingLeft) 74 return h 75 } 76 77 // BigToHash sets byte representation of b to Hash. 78 // If b is larger than len(h), b will be cropped from the left. 79 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } 80 81 // HexToHash sets byte representation of s to Hash. 82 // If b is larger than len(h), b will be cropped from the left. 83 func HexToHash(s string) (hash Hash, err error) { 84 bytes, err := FromHex(s) 85 if err != nil { 86 return 87 } 88 hash = BytesToHash(bytes) 89 return 90 } 91 92 func HexToHashNoError(s string) (hash Hash) { 93 hash, err := HexToHash(s) 94 utilfuncs.PanicIfError(err, "hexToHash") 95 return 96 } 97 98 func HexStringsToHashes(ss []string) (hashes Hashes, err error) { 99 hashes = make([]Hash, len(ss)) 100 for i, s := range ss { 101 hashes[i], err = HexToHash(s) 102 if err != nil { 103 return 104 } 105 } 106 return 107 } 108 109 // ToBytes convers hash to []byte. 110 func (h Hash) ToBytes() []byte { return h.Bytes[:] } 111 112 // Big converts an Hash to a big integer. 113 func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h.Bytes[:]) } 114 115 // Hex converts a Hash to a hex string. 116 func (h Hash) Hex() string { return hexutil.Encode(h.Bytes[:]) } 117 118 // TerminalString implements log.TerminalStringer, formatting a string for console 119 // output during logging. 120 func (h Hash) TerminalString() string { 121 return fmt.Sprintf("%x…%x", h.Bytes[:3], h.Bytes[len(h.Bytes)-3:]) 122 } 123 124 // String implements the stringer interface and is used also by the logger when 125 // doing full logging into a file. 126 func (h Hash) String() string { 127 s := h.Hex() 128 return "0x" + s[len(s)-8:] 129 //return h.Hex()[:10] 130 } 131 132 // Format implements fmt.Formatter, forcing the byte slice to be formatted as is, 133 // without going through the stringer interface used for logging. 134 //func (h Hash) Format(s fmt.State, c rune) { 135 // fmt.Fprintf(s, "%"+string(c), h.KeyBytes) 136 //} 137 138 // UnmarshalText parses an Hash in hex syntax. 139 func (h *Hash) UnmarshalText(input []byte) error { 140 return hexutil.UnmarshalFixedText("Hash", input, h.Bytes[:]) 141 } 142 143 // UnmarshalJSON parses an Hash in hex syntax. 144 func (h *Hash) UnmarshalJSON(input []byte) error { 145 return hexutil.UnmarshalFixedJSON(hashT, input, h.Bytes[:]) 146 } 147 148 // MarshalText returns the hex representation of h. 149 func (h Hash) MarshalText() ([]byte, error) { 150 return hexutil.Bytes(h.Bytes[:]).MarshalText() 151 } 152 153 // SetBytes sets the Hash to the value of b. 154 // If b is larger than len(h), panic. It usually indicates a logic error. 155 func (h *Hash) MustSetBytes(b []byte, padding Padding) { 156 if len(b) > HashLength { 157 panic(fmt.Sprintf("bytes to set is longer than expected length: %d > %d", len(b), HashLength)) 158 } 159 160 h.Bytes = [HashLength]byte{} 161 switch padding { 162 case PaddingLeft: 163 copy(h.Bytes[HashLength-len(b):], b) 164 case PaddingRight: 165 copy(h.Bytes[:], b) 166 case PaddingNone: 167 if len(b) != HashLength { 168 panic(fmt.Sprintf("bytes to set is not expected length: %d != %d", len(b), HashLength)) 169 } 170 copy(h.Bytes[:], b) 171 } 172 173 } 174 175 func (h *Hash) SetBytes(b []byte) error { 176 if len(b) > HashLength { 177 return fmt.Errorf("byte to set is longer than expected length: %d > %d", len(b), HashLength) 178 } 179 h.Bytes = [HashLength]byte{} 180 copy(h.Bytes[:], b) 181 return nil 182 } 183 184 // Generate implements testing/quick.Generator. 185 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { 186 m := rand.Intn(HashLength) 187 for i := HashLength - 1; i > m; i-- { 188 h.Bytes[i] = byte(rand.Uint32()) 189 } 190 return reflect.ValueOf(h) 191 } 192 193 // Cmp compares two hashes. 194 // Returns 0 if two hashes are same. 195 // Returns -1 if the self hash is less than parameter hash. 196 // Returns 1 if the self hash is larger than parameter hash. 197 func (h Hash) Cmp(another Hash) int { 198 for i := 0; i < HashLength; i++ { 199 if h.Bytes[i] < another.Bytes[i] { 200 return -1 201 } else if h.Bytes[i] > another.Bytes[i] { 202 return 1 203 } 204 } 205 return 0 206 } 207 208 func (a Hashes) Len() int { return len(a) } 209 func (a Hashes) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 210 func (a Hashes) Less(i, j int) bool { return a[i].Hex() < a[j].Hex() } 211 212 func (h Hashes) String() string { 213 if h == nil { 214 return "" 215 } 216 var strs []string 217 for _, v := range h { 218 strs = append(strs, v.String()) 219 } 220 return strings.Join(strs, ", ") 221 } 222 223 func randomHash() Hash { 224 v := math.NewBigInt(rand.Int63()) 225 sh := BigToHash(v.Value) 226 h := sha256.New() 227 data := []byte("456544546fhjsiodiruheswer8ih") 228 h.Write(sh.Bytes[:]) 229 h.Write(data) 230 sum := h.Sum(nil) 231 sh.MustSetBytes(sum, PaddingRight) 232 return sh 233 } 234 235 func RandomHash() Hash { 236 return randomHash() 237 } 238 239 func RandomAddress() Address { 240 return randomAddress() 241 } 242 243 func randomAddress() Address { 244 v := math.NewBigInt(rand.Int63()) 245 adr := BigToAddress(v.Value) 246 h := sha256.New() 247 data := []byte("abcd8342804fhddhfhisfdyr89") 248 h.Write(adr.Bytes[:]) 249 h.Write(data) 250 sum := h.Sum(nil) 251 adr.MustSetBytes(sum[:20]) 252 return adr 253 }