github.com/anacrolix/torrent@v1.61.0/types/infohash/infohash.go (about) 1 package infohash 2 3 import ( 4 "bytes" 5 "crypto/sha1" 6 "crypto/sha256" 7 "encoding" 8 "encoding/hex" 9 "fmt" 10 ) 11 12 const Size = 20 13 14 // 20-byte SHA1 hash used for info and pieces. 15 type T [Size]byte 16 17 var _ fmt.Formatter = (*T)(nil) 18 19 func (l T) Compare(r T) int { 20 return bytes.Compare(l.Bytes(), r.Bytes()) 21 } 22 23 func (t T) Format(f fmt.State, c rune) { 24 // TODO: I can't figure out a nice way to just override the 'x' rune, since it's meaningless 25 // with the "default" 'v', or .String() already returning the hex. 26 f.Write([]byte(t.HexString())) 27 } 28 29 func (t T) Bytes() []byte { 30 return t[:] 31 } 32 33 func (t T) AsString() string { 34 return string(t[:]) 35 } 36 37 func (t T) String() string { 38 return t.HexString() 39 } 40 41 func (t T) HexString() string { 42 return fmt.Sprintf("%x", t[:]) 43 } 44 45 func (t *T) FromHexString(s string) (err error) { 46 if len(s) != 2*Size { 47 err = fmt.Errorf("hash hex string has bad length: %d", len(s)) 48 return 49 } 50 n, err := hex.Decode(t[:], []byte(s)) 51 if err != nil { 52 return 53 } 54 if n != Size { 55 panic(n) 56 } 57 return 58 } 59 60 func (t *T) IsZero() bool { 61 return *t == T{} 62 } 63 64 var ( 65 _ encoding.TextUnmarshaler = (*T)(nil) 66 _ encoding.TextMarshaler = T{} 67 ) 68 69 func (t *T) UnmarshalText(b []byte) error { 70 return t.FromHexString(string(b)) 71 } 72 73 func (t T) MarshalText() (text []byte, err error) { 74 return []byte(t.HexString()), nil 75 } 76 77 func FromHexString(s string) (h T) { 78 err := h.FromHexString(s) 79 if err != nil { 80 panic(err) 81 } 82 return 83 } 84 85 func HashBytes(b []byte) (ret T) { 86 hasher := sha1.New() 87 hasher.Write(b) 88 copy(ret[:], hasher.Sum(nil)) 89 return 90 } 91 92 func HashBytesV2(b []byte) (ret T) { 93 hasher := sha256.New() 94 hasher.Write(b) 95 copy(ret[:], hasher.Sum(nil)) 96 return 97 }