bep33.go 857 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package krpc
  2. import (
  3. "crypto/sha1"
  4. "math"
  5. "math/bits"
  6. "net"
  7. )
  8. const (
  9. m = 256 * 8
  10. k = 2
  11. )
  12. type ScrapeBloomFilter [256]byte
  13. // Note that if you intend for an IP to be in the IPv4 space, you might want to trim it to 4 bytes
  14. // with IP.To4.
  15. func (me *ScrapeBloomFilter) AddIp(ip net.IP) {
  16. h := sha1.New()
  17. h.Write(ip)
  18. var sum [20]byte
  19. h.Sum(sum[:0])
  20. me.addK(int(sum[0]) | int(sum[1])<<8)
  21. me.addK(int(sum[2]) | int(sum[3])<<8)
  22. }
  23. func (me *ScrapeBloomFilter) addK(index int) {
  24. index %= m
  25. me[index/8] |= 1 << (index % 8)
  26. }
  27. func (me ScrapeBloomFilter) countZeroes() (ret int) {
  28. for _, i := range me {
  29. ret += 8 - bits.OnesCount8(i)
  30. }
  31. return
  32. }
  33. func (me *ScrapeBloomFilter) EstimateCount() float64 {
  34. if me == nil {
  35. return 0
  36. }
  37. c := float64(me.countZeroes())
  38. if c > m-1 {
  39. c = m - 1
  40. }
  41. return math.Log(c/m) / (k * math.Log(1.-1./m))
  42. }