package common import ( "fmt" "math/big" "net" ) func iptouint(ip net.IP) uint32 { ip = ip.To4() return uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[3]) } func toip(num uint32) string { return fmt.Sprintf("%d.%d.%d.%d", (num>>24)&255, (num>>16)&255, (num>>8)&255, num&255) } // per-cidr linear congruential generator for efficient randomized target ip ordering, ty claude func lcgcidr(cidr string, out chan<- string) { // lcg constants const a uint64 = 1664525 const c uint64 = 1013904223 _, ipnet, _ := net.ParseCIDR(cidr) start := iptouint(ipnet.IP) ones, bits := ipnet.Mask.Size() addrcount := new(big.Int).Lsh(big.NewInt(1), uint(bits-ones)) x := uint64(start) m := uint64(addrcount.Uint64()) for i := uint64(0); i < m; i++ { x = (a*x + c) % (1 << 32) // mod of full 32bit addr count ip := toip(uint32((x % m) + uint64(start))) out <- ip } }