potknocker/common/lcg.go
2024-08-30 18:51:26 -05:00

43 lines
909 B
Go

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
}
}