From 9f26ab1adcd09b971df767200bec8158e4135774 Mon Sep 17 00:00:00 2001 From: Taevas <67872932+TTTaevas@users.noreply.github.com> Date: Tue, 13 Dec 2022 21:04:03 +0100 Subject: [PATCH] Added Go --- Go/README.md | 17 +++++ Go/index.go | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 Go/README.md create mode 100644 Go/index.go diff --git a/Go/README.md b/Go/README.md new file mode 100644 index 0000000..b0519ba --- /dev/null +++ b/Go/README.md @@ -0,0 +1,17 @@ +# Website-Finder: Go + +## REQUIREMENT + +[Go](https://go.dev/) ([Snap Store for Linux](https://snapcraft.io/go)) + +## HOW TO RUN + +```sh +$ go run index.go +``` + +Note: Due to how randomness works in Go, if you're gonna run the script multiple times in a row, you may want to change the minimum/maximum length of URLs before running the script again in order to have different results + +## OTHER STUFF + +More details are available on [the readme in the root folder](../README.md) diff --git a/Go/index.go b/Go/index.go new file mode 100644 index 0000000..63c22b9 --- /dev/null +++ b/Go/index.go @@ -0,0 +1,183 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + "log" + "math/rand" + "net/http" + "os" + "strconv" + "strings" + "time" +) + +// Note to self: In type structs, everything will be falsey/empty if properties do not start with an uppercased letter +type Defaults struct { + Times int + Protocols []string + Domains []string + Second int + Log bool + Min int + Max int +} + +// Note to self: The strings after the type defines what names'll be used in the json file (it'll use uppercased 1st letter version otherwise) +type Website struct { + Website_url string `json:"website_url"` + Response_type string `json:"response_type"` + Response_code string `json:"response_code"` + Response_details string `json:"response_details"` +} + +func indexOf(arr []string, element string) int { // 💀💀💀💀 + for i := 0; i < len(arr); i++ { + if arr[i] == element { + return i + } + } + return -1 +} + +func main_loop(times int, domains, protocols []string, logging bool, min, max, second int, report_file_name string) { + var json_text []Website + for i := 0; i < times; i++ { + var url string = url_generator(protocols, domains, min, max, second) + if logging { + log.Printf("%s (%d/%d)", url, i+1, times) + } + response, err := http.Get(url) + if err != nil { // Unlike in, say, Crystal, errors in Go are kinda just strings instead of having different types + var str = err.Error() + if !strings.Contains(str, "no such host") { + log.Printf("%s exists!", url) + json_text = append(json_text, Website{ + Website_url: url, + Response_type: "ERROR", + Response_code: "UNKNOWN", // No Go error contains such a thing + Response_details: str, + }) + } + continue + } + log.Printf("%s exists!", url) + json_text = append(json_text, Website{ + Website_url: url, + Response_type: "SUCCESS", + Response_code: strconv.Itoa(response.StatusCode), + Response_details: response.Status[4:], + }) + } + + json_object, err := json.Marshal(json_text) + if err != nil { + log.Print("Error while creating the report: ", err) + log.Fatal("Here was the json_text: ", json_text) + } + report_file, err := os.Create(report_file_name) + if err != nil { + log.Fatal("Error while creating the report file: ", err) + } + defer report_file.Close() + report_file.Write(json_object) + if err != nil { + log.Fatal("Error while writing in the report file: ", err) + } + + end_date := time.Now() + log.Printf("\nFinished at %sh%sm", strconv.Itoa(end_date.Hour()), strconv.Itoa(end_date.Minute())) +} + +func url_generator(protocols, domains []string, min, max, second int) string { + var result string = protocols[rand.Intn(len(protocols))] + "://" + var url_length int = rand.Intn(max-min) + min + var characters string = "abcdefghijklmnopqrstuvwxyz0123456789" + for i := 0; i < url_length; i++ { + result += string(characters[rand.Intn(len(characters))]) + } + if rand.Intn(99)+1 <= second { + result += "." + domains[rand.Intn(len(domains))] + } + result += "." + domains[rand.Intn(len(domains))] + return result +} + +func main() { + log.SetFlags(0) + + content, err := ioutil.ReadFile("../defaults.json") + if err != nil { + log.Fatal("Error opening defaults.json: ", err) + } + + var defaults Defaults + err = json.Unmarshal(content, &defaults) + if err != nil { + log.Fatal("Error parsing defaults.json: ", err) + } + + var times int + if indexOf(os.Args, "-t") != -1 { + times, err = strconv.Atoi(os.Args[indexOf(os.Args, "-t")+1]) + if err != nil { + log.Fatal("Error understanding the -t argument: ", err) + } + } else { + times = defaults.Times + } + var protocols []string + if indexOf(os.Args, "-p") != -1 { + protocols = strings.Split(os.Args[indexOf(os.Args, "-p")+1], ",") + } else { + protocols = defaults.Protocols + } + var domains []string + if indexOf(os.Args, "-d") != -1 { + domains = strings.Split(os.Args[indexOf(os.Args, "-p")+1], ",") + } else { + domains = defaults.Domains + } + var second int + if indexOf(os.Args, "-s") != -1 { + second, err = strconv.Atoi(os.Args[indexOf(os.Args, "-s")+1]) + if err != nil { + log.Fatal("Error understanding the -s argument: ", err) + } + } else { + second = defaults.Second + } + var logging bool // "log", unlike in other scripts, refers to a package we are using + if indexOf(os.Args, "-l") != -1 { + logging = true + } else { + logging = defaults.Log + } + var min int + if indexOf(os.Args, "-min") != -1 { + min, err = strconv.Atoi(os.Args[indexOf(os.Args, "-min")+1]) + if err != nil { + log.Fatal("Error understanding the -min argument: ", "err") + } + } else { + min = defaults.Min + } + var max int + if indexOf(os.Args, "-max") != -1 { + max, err = strconv.Atoi(os.Args[indexOf(os.Args, "-max")+1]) + if err != nil { + log.Fatal("Error understanding the -max argument: ", err) + } + } else { + max = defaults.Max + } + + date := time.Now() + log.Printf("\nI am going to look for websites through %d random URLS (min length %d and max length %d) with the following domains: %+q", times, min, max, domains) + log.Printf("These URLs will use the protocols %+q", protocols) + log.Printf("and each of those URLs have %d in a 100 chance to have a second level domain", second) + log.Printf("Started at %sh%sm", strconv.Itoa(date.Hour()), strconv.Itoa(date.Minute())) + + var report_file_name string = "GO_report_" + strconv.Itoa(date.Day()) + strconv.Itoa(date.Hour()) + strconv.Itoa(date.Minute()) + ".json" + main_loop(times, domains, protocols, logging, min, max, second, report_file_name) +}