id.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package krpc
  2. import (
  3. crand "crypto/rand"
  4. "encoding"
  5. "encoding/hex"
  6. "fmt"
  7. "github.com/anacrolix/torrent/bencode"
  8. "github.com/anacrolix/dht/v2/int160"
  9. )
  10. func RandomNodeID() (id ID) {
  11. crand.Read(id[:])
  12. return
  13. }
  14. type ID [20]byte
  15. var (
  16. _ interface {
  17. bencode.Unmarshaler
  18. encoding.TextUnmarshaler
  19. } = (*ID)(nil)
  20. _ bencode.Marshaler = ID{}
  21. _ fmt.Formatter = ID{}
  22. )
  23. func (h ID) Format(f fmt.State, c rune) {
  24. // See metainfo.Hash.
  25. f.Write([]byte(h.String()))
  26. }
  27. func IdFromString(s string) (id ID) {
  28. if n := copy(id[:], s); n != 20 {
  29. panic(n)
  30. }
  31. return
  32. }
  33. func (id ID) MarshalBencode() ([]byte, error) {
  34. return []byte("20:" + string(id[:])), nil
  35. }
  36. func (id *ID) UnmarshalBencode(b []byte) error {
  37. var s string
  38. if err := bencode.Unmarshal(b, &s); err != nil {
  39. return err
  40. }
  41. if n := copy(id[:], s); n != 20 {
  42. return fmt.Errorf("string has wrong length: %d", n)
  43. }
  44. return nil
  45. }
  46. func (id *ID) UnmarshalText(b []byte) (err error) {
  47. n, err := hex.Decode(id[:], b)
  48. if err != nil {
  49. return
  50. }
  51. if n != len(*id) {
  52. err = fmt.Errorf("expected %v bytes, only got %v", len(*id), n)
  53. }
  54. return
  55. }
  56. func (id ID) String() string {
  57. return hex.EncodeToString(id[:])
  58. }
  59. func (id ID) Int160() int160.T {
  60. return int160.FromByteArray(id)
  61. }
  62. func (id ID) IsZero() bool {
  63. return id == [20]byte{}
  64. }