package common import ( "crypto/rand" "encoding/binary" "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) } func seed() int64 { var n int64 if err := binary.Read(rand.Reader, binary.LittleEndian, &n); err != nil { return 1337 } return n } // per-cidr linear congruential generator for efficient randomized target ip ordering, ty claude func LCG(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(seed()) ^ uint64(start) // seed for unique randomization per execution 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 } }