golcg

- Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.acid.vegas/-c.git
Log | Files | Refs | Archive | README | LICENSE

commit 5853af04903f8e855d60258766991992620afea8
parent d6ad25efdb9d45c2fee6cd4340e75a7acfbd65b5
Author: acidvegas <acid.vegas@acid.vegas>
Date: Sun, 1 Dec 2024 01:32:40 -0500

Package ready for go get & import usage

Diffstat:
MREADME.md | 4++--
Acmd/golcg/main.go | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgo.mod | 4++--
Mgolcg.go | 82+++++++++++++++++++++----------------------------------------------------------

4 files changed, 80 insertions(+), 64 deletions(-)

diff --git a/README.md b/README.md
@@ -19,7 +19,7 @@
 
 ## Installation 
 ```bash
-go install github.com/acidvegas/golcg
+go install github.com/acidvegas/golcg/cmd/golcg@latest
 ```
 
 ## Usage
@@ -91,7 +91,6 @@ Every IPv4 address is fundamentally a 32-bit number. For example, the IP address
 192.168.1.1 = (192 × 256³) + (168 × 256²) + (1 × 256¹) + (1 × 256⁰)
              = 3232235777
 ```
-
 This integer representation allows us to treat IP ranges as simple number sequences. A CIDR block like "192.168.0.0/16" becomes a continuous range of integers:
 - Start: 192.168.0.0   → 3232235520
 - End:   192.168.255.255 → 3232301055
@@ -143,3 +142,4 @@ The sharding system employs an interleaved approach that ensures even distributi
 ---
 
 ###### Mirrors: [acid.vegas](https://git.acid.vegas/golcg) • [SuperNETs](https://git.supernets.org/acidvegas/golcg) • [GitHub](https://github.com/acidvegas/golcg) • [GitLab](https://gitlab.com/acidvegas/golcg) • [Codeberg](https://codeberg.org/acidvegas/golcg)
+
diff --git a/cmd/golcg/main.go b/cmd/golcg/main.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"strconv"
+
+	"github.com/acidvegas/golcg"
+)
+
+const Version = "1.0.0"
+
+func main() {
+	cidr := flag.String("cidr", "", "Target IP range in CIDR format")
+	shardNum := flag.Int("shard-num", 1, "Shard number (1-based)")
+	totalShards := flag.Int("total-shards", 1, "Total number of shards")
+	seed := flag.Int("seed", 0, "Random seed for LCG")
+	stateStr := flag.String("state", "", "Resume from specific LCG state")
+	version := flag.Bool("version", false, "Show version information")
+	flag.Parse()
+
+	if *version {
+		fmt.Printf("golcg version %s\n", Version)
+		os.Exit(0)
+	}
+
+	if *cidr == "" {
+		fmt.Println("Error: CIDR is required")
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	var state *uint32
+	if *stateStr != "" {
+		stateVal, err := strconv.ParseUint(*stateStr, 10, 32)
+		if err != nil {
+			fmt.Printf("Error parsing state: %v\n", err)
+			os.Exit(1)
+		}
+		stateUint32 := uint32(stateVal)
+		state = &stateUint32
+	}
+
+	stream, err := golcg.IPStream(*cidr, *shardNum, *totalShards, *seed, state)
+	if err != nil {
+		fmt.Printf("Error: %v\n", err)
+		os.Exit(1)
+	}
+
+	for ip := range stream {
+		fmt.Println(ip)
+	}
+}
diff --git a/go.mod b/go.mod
@@ -1,3 +1,3 @@
-module golcg
+module github.com/acidvegas/golcg
 
-go 1.23.2
+go 1.21
diff --git a/golcg.go b/golcg.go
@@ -1,42 +1,40 @@
-package main
+package golcg
 
 import (
 	"errors"
-	"flag"
 	"fmt"
 	"math/rand"
 	"net"
 	"os"
 	"path/filepath"
-	"strconv"
 	"strings"
 	"time"
 )
 
 type LCG struct {
-	m       uint32
-	a       uint32
-	c       uint32
-	current uint32
+	M       uint32
+	A       uint32
+	C       uint32
+	Current uint32
 }
 
 func NewLCG(seed int, m uint32) *LCG {
 	return &LCG{
-		m:       m,
-		a:       1664525,
-		c:       1013904223,
-		current: uint32(seed),
+		M:       m,
+		A:       1664525,
+		C:       1013904223,
+		Current: uint32(seed),
 	}
 }
 
 func (l *LCG) Next() uint32 {
-	l.current = (l.a*l.current + l.c) % l.m
-	return l.current
+	l.Current = (l.A*l.Current + l.C) % l.M
+	return l.Current
 }
 
 type IPRange struct {
-	start uint32
-	total uint32
+	Start uint32
+	Total uint32
 }
 
 func NewIPRange(cidr string) (*IPRange, error) {
@@ -52,17 +50,17 @@ func NewIPRange(cidr string) (*IPRange, error) {
 	total := broadcast - start + 1
 
 	return &IPRange{
-		start: start,
-		total: uint32(total),
+		Start: start,
+		Total: uint32(total),
 	}, nil
 }
 
 func (r *IPRange) GetIPAtIndex(index uint32) (string, error) {
-	if index >= r.total {
+	if index >= r.Total {
 		return "", errors.New("IP index out of range")
 	}
 
-	ip := uint32ToIP(r.start + index)
+	ip := uint32ToIP(r.Start + index)
 	return ip.String(), nil
 }
 
@@ -102,12 +100,12 @@ func IPStream(cidr string, shardNum, totalShards, seed int, state *uint32) (<-ch
 
 	lcg := NewLCG(seed+shardIndex, 1<<32-1)
 	if state != nil {
-		lcg.current = *state
+		lcg.Current = *state
 	}
 
-	shardSize := ipRange.total / uint32(totalShards)
+	shardSize := ipRange.Total / uint32(totalShards)
 
-	if uint32(shardIndex) < (ipRange.total % uint32(totalShards)) {
+	if uint32(shardIndex) < (ipRange.Total % uint32(totalShards)) {
 		shardSize++
 	}
 
@@ -117,7 +115,7 @@ func IPStream(cidr string, shardNum, totalShards, seed int, state *uint32) (<-ch
 		remaining := shardSize
 
 		for remaining > 0 {
-			index := lcg.Next() % ipRange.total
+			index := lcg.Next() % ipRange.Total
 			if totalShards == 1 || index%uint32(totalShards) == uint32(shardIndex) {
 				ip, err := ipRange.GetIPAtIndex(index)
 				if err != nil {
@@ -127,7 +125,7 @@ func IPStream(cidr string, shardNum, totalShards, seed int, state *uint32) (<-ch
 				remaining--
 
 				if remaining%1000 == 0 {
-					SaveState(seed, cidr, shardNum, totalShards, lcg.current)
+					SaveState(seed, cidr, shardNum, totalShards, lcg.Current)
 				}
 			}
 		}
@@ -135,39 +133,3 @@ func IPStream(cidr string, shardNum, totalShards, seed int, state *uint32) (<-ch
 
 	return out, nil
 }
-
-func main() {
-	cidr := flag.String("cidr", "", "Target IP range in CIDR format")
-	shardNum := flag.Int("shard-num", 1, "Shard number (1-based)")
-	totalShards := flag.Int("total-shards", 1, "Total number of shards")
-	seed := flag.Int("seed", 0, "Random seed for LCG")
-	stateStr := flag.String("state", "", "Resume from specific LCG state")
-	flag.Parse()
-
-	if *cidr == "" {
-		fmt.Println("Error: CIDR is required")
-		flag.Usage()
-		os.Exit(1)
-	}
-
-	var state *uint32
-	if *stateStr != "" {
-		stateVal, err := strconv.ParseUint(*stateStr, 10, 32)
-		if err != nil {
-			fmt.Printf("Error parsing state: %v\n", err)
-			os.Exit(1)
-		}
-		stateUint32 := uint32(stateVal)
-		state = &stateUint32
-	}
-
-	stream, err := IPStream(*cidr, *shardNum, *totalShards, *seed, state)
-	if err != nil {
-		fmt.Printf("Error: %v\n", err)
-		os.Exit(1)
-	}
-
-	for ip := range stream {
-		fmt.Println(ip)
-	}
-}