commit 93d30eeb52a612f908e33f3d1bc79d74cd3118e5 Author: Isaac Lewis Date: Thu Nov 6 11:13:23 2025 -0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dd90b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +.DS_Store +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Code coverage profiles and other test artifacts +*.out +coverage.* +*.coverprofile +profile.cov + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# env file +.env + +# Editor/IDE +# .idea/ +# .vscode/ diff --git a/dist/rot-darwin b/dist/rot-darwin new file mode 100755 index 0000000..c062f36 Binary files /dev/null and b/dist/rot-darwin differ diff --git a/dist/rot-linux_amd64 b/dist/rot-linux_amd64 new file mode 100755 index 0000000..e7dca12 Binary files /dev/null and b/dist/rot-linux_amd64 differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5fb6a80 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module rot + +go 1.22.1 diff --git a/main.go b/main.go new file mode 100644 index 0000000..ccdc16c --- /dev/null +++ b/main.go @@ -0,0 +1,106 @@ +package main + +import ( + "bytes" + "fmt" + "math/rand" + "net" + "os" + "time" +) + +func getRandomAddress() string { + ip1 := rand.Intn(256) + ip2 := rand.Intn(256) + ip3 := rand.Intn(256) + ip4 := rand.Intn(256) + return fmt.Sprintf("%d.%d.%d.%d", ip1, ip2, ip3, ip4) +} + +func offgas(r rune) { + address := getRandomAddress() + conn, err := net.Dial("udp", address+":7") + if err != nil { + fmt.Println("Error connecting to:", address, err) + } + defer conn.Close() + + // Set write timeout + conn.SetWriteDeadline(time.Now().Add(3 * time.Second)) + + // Send the character + _, err = conn.Write([]byte(string(r))) + if err != nil { + fmt.Println("Error sending data to:", address, err) + return + } +} + +func main() { + // get poem.txt and index.html locations from args, if possible + poemFile := "poem.txt" + indexFile := "index.html" + if len(os.Args) == 3 { + poemFile = os.Args[1] + indexFile = os.Args[2] + } + + // get string from poem.txt + str, err := os.ReadFile(poemFile) + if err != nil { + fmt.Println("Error reading file:", err) + return + } + + bstr := []byte(str) + lastRune := rune(0) + + randomByteSwitch := func(r rune) rune { + dec := rand.Float64() + if dec < 0.003 { + lastRune = r + if r == 10 || r == 13 { + return r + } + + char := rand.Float64() + if char > 0.3 { + return rune(rand.Int31n(8191) + 97) // a-z + } + if char < 0.01 { + return rand.Int31n(128591-128513) + 128513 + } + + return rand.Int31n(11359) + } + if dec < 0.007 { + if dec > 0.001 && r == 10 || r == 13 { + if lastRune == 10 || lastRune == 13 { + offgas(r) + lastRune = r + return -1 + } + lastRune = r + return r + } + + offgas(r) + lastRune = r + return -1 + } + + return r + } + + bstr = bytes.Map(randomByteSwitch, bstr) + + outstr := "poem, rotting

rotting

This poem rots over time, eventually disappearing. New words are added to the top of the heap periodically. It offgasses into the internet via random UDP echo packets. Few hosts respond.

" + string(bstr) + "

" + + // write to index.html + err = os.WriteFile(indexFile, []byte(outstr), 0644) + err = os.WriteFile(poemFile, bstr, 0644) + if err != nil { + fmt.Println("Error writing file:", err) + return + } +} diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..6cbe746 --- /dev/null +++ b/www/index.html @@ -0,0 +1 @@ +poem, rotting

rotting

This poem rots over time, eventually disappearing. New words are added to the top of the heap periodically. It offgasses into the internet via random UDP echo packets. Few hosts respond.

\ No newline at end of file diff --git a/www/style.css b/www/style.css new file mode 100644 index 0000000..a8ba97c --- /dev/null +++ b/www/style.css @@ -0,0 +1,15 @@ +body { + padding: 2px; + max-width: 550px; + margin: 0 auto; +} + +h1 { + font-size: 4em; + margin-bottom: 0px; +} + +#poem { + margin-top: 70px; + white-space: pre; +}