github.com/anacrolix/torrent@v1.61.0/types/infohash-v2/infohash-v2.go (about)

     1  package infohash_v2
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"unsafe"
     9  
    10  	"github.com/multiformats/go-multihash"
    11  
    12  	"github.com/anacrolix/torrent/types/infohash"
    13  )
    14  
    15  const Size = sha256.Size
    16  
    17  // 32-byte SHA2-256 hash. See BEP 52.
    18  type T [Size]byte
    19  
    20  var _ fmt.Formatter = (*T)(nil)
    21  
    22  func (t *T) Format(f fmt.State, c rune) {
    23  	// TODO: I can't figure out a nice way to just override the 'x' rune, since it's meaningless
    24  	// with the "default" 'v', or .String() already returning the hex.
    25  	f.Write([]byte(t.HexString()))
    26  }
    27  
    28  func (t *T) Bytes() []byte {
    29  	return t[:]
    30  }
    31  
    32  func (t *T) AsString() string {
    33  	return string(t[:])
    34  }
    35  
    36  func (t *T) String() string {
    37  	return t.HexString()
    38  }
    39  
    40  func (t *T) HexString() string {
    41  	return fmt.Sprintf("%x", t[:])
    42  }
    43  
    44  func (t *T) FromHexString(s string) (err error) {
    45  	if len(s) != 2*Size {
    46  		err = fmt.Errorf("hash hex string has bad length: %d", len(s))
    47  		return
    48  	}
    49  	n, err := hex.Decode(t[:], []byte(s))
    50  	if err != nil {
    51  		return
    52  	}
    53  	if n != Size {
    54  		panic(n)
    55  	}
    56  	return
    57  }
    58  
    59  // Truncates the hash to 20 bytes for use in auxiliary interfaces, like DHT and trackers.
    60  func (t *T) ToShort() (short *infohash.T) {
    61  	return (*infohash.T)(unsafe.Pointer(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 := sha256.New()
    87  	hasher.Write(b)
    88  	copy(ret[:], hasher.Sum(nil))
    89  	return
    90  }
    91  
    92  func ToMultihash(t T) multihash.Multihash {
    93  	b, _ := multihash.Encode(t[:], multihash.SHA2_256)
    94  	return b
    95  }