This commit is contained in:
darkmage 2024-01-14 17:48:59 -06:00
commit 2dec270b1d
2 changed files with 98 additions and 0 deletions

15
README.md Normal file
View File

@ -0,0 +1,15 @@
```
<@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.
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

83
main.go Normal file
View File

@ -0,0 +1,83 @@
// linear congruential generator written in go
// by darkmage
// https://www.evildojo.com
// https://www.twitter.com/evildojo666
package main
import (
"fmt"
"time"
"os"
"math"
"math/rand"
"strconv"
"sync"
)
// define a global sieve
var sieve []bool
var wg sync.WaitGroup
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()
}
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: go run main.go <seed> <shard_count>")
os.Exit(1)
}
seed, err := strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
fmt.Println("Error: ", err)
os.Exit(1)
}
rand := rand.New(rand.NewSource(seed))
var max int64 = 256*256*256*256
var start int64 = rand.Int63n(max)
fmt.Println("start:", start)
shard_count, err := strconv.ParseInt(os.Args[2], 10, 64)
if err != nil {
fmt.Println("Error: ", err)
os.Exit(1)
}
fmt.Println("shard_count:", shard_count)
var move int64 = (int64(math.Sqrt(float64(max))) + 1) * shard_count
fmt.Println("move:", move)
sieve = make([]bool, max)
start_time := time.Now()
for i := int64(0); i < shard_count; i++ {
fmt.Println("shard:", i)
wg.Add(1)
go run_sieve(max, start, move, i, shard_count)
}
wg.Wait()
end_time := time.Now()
fmt.Println("Completed iterating numbers")
fmt.Println("Time elapsed:", end_time.Sub(start_time))
fmt.Println("Checking sieve")
start_time = time.Now()
for i := int64(0); i < max; i++ {
if !sieve[i] {
fmt.Println(os.Stderr, "Error, not all numbers flipped")
os.Exit(1)
}
}
end_time = time.Now()
fmt.Println("Time elapsed:", end_time.Sub(start_time))
}