An example of how to write an LCG in golang.
Go to file
darkmage 0eff81b5d5 updated readme 2024-01-14 17:54:31 -06:00
README.md updated readme 2024-01-14 17:54:31 -06:00
main.go first 2024-01-14 17:48:59 -06:00

README.md

golcg

Chilling in #dev on irc.supernets.org one day, acidvegas hit me up like:

<@acidvegas> darkmage: how easily do you think you could
<@acidvegas> isolate masscans
<@acidvegas> range function
<@acidvegas> into golang or python
<@acidvegas> aka
<@acidvegas> generating ip addresses
<@acidvegas> randomly
<@acidvegas> for massive ranges like 0.0.0.0/0
<@acidvegas> in a memory safe manner

Really easily, it turns out.


usage

go run main.go <seed> <shard_count>

how it works

You can generate numbers in a predictable manner by feeding a custom seed to an RNG to find a random starting position, modifying it with an offset relative to which shard (assuming you're using multiple shards but not required) is generating addresses (so that no two shards generate the same address).

func run_sieve(max int64, start int64, move int64, shard_num int64, shard_count int64) {
    var current int64 = start + shard_num
    if current > max-1 {
        current = current % max
    }
    for i := int64(0); i <= max/shard_count; i++ {
        sieve[current] = true
        current = current + move 
        if current > max-1 {
            current = current % max
        }
    }
    defer wg.Done()
}

The meat of this process is handled with this function, run_sieve.

We can generate random start indices or we can start at 0, and then we apply the shard offset. If the resulting start value is beyond our range, we roll the number around to the beginning again with a modulus. We also keep track of a global sieve that contains booleans to verify we hit every number.