From f2f3c1aff15cf925899807140ed7879bae278684 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 2 Jan 2024 03:36:46 -0500 Subject: [PATCH] init --- .gitignore | 2 + README.MD | 11 ++++ create_db.go | 95 +++++++++++++++++++++++++++++++ go.mod | 5 ++ go.sum | 2 + readData.go | 130 ++++++++++++++++++++++++++++++++++++++++++ writeData.go | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 400 insertions(+) create mode 100644 .gitignore create mode 100644 README.MD create mode 100644 create_db.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 readData.go create mode 100644 writeData.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0b4c8c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +english_words.db +*.txt diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..e249206 --- /dev/null +++ b/README.MD @@ -0,0 +1,11 @@ +# xorWords + +## Install +``` +$ go get github.com/mattn/go-sqlite3 +$ go run create_db.go +``` +## Create xored data +$ go run writeData.go +## Fetch data +$ go run readData.go diff --git a/create_db.go b/create_db.go new file mode 100644 index 0000000..9c809fe --- /dev/null +++ b/create_db.go @@ -0,0 +1,95 @@ +package main + +import ( + "database/sql" + "fmt" + "io/ioutil" + "log" + "strings" + + _ "github.com/mattn/go-sqlite3" +) + +var topEnglishWords = []string{ + ".", ",", "!", ";", "?", "(", ")", "'", "\"", + "the", "and", "of", "to", "a", "in", "is", "it", "you", "that", + "he", "was", "for", "on", "are", "with", "as", "I", "his", "they", + "be", "at", "one", "have", "this", "from", "or", "had", "by", "hot", + "word", "but", "what", "some", "we", "can", "out", "other", "were", + "all", "there", "when", "up", "use", "your", "how", "said", "an", + "each", "she", "which", "do", "their", "time", "if", "will", "way", + "about", "many", "then", "them", "write", "would", "like", "so", "these", +} + +func main() { + // Open SQLite database file + db, err := sql.Open("sqlite3", "./english_words.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Create table + _, err = db.Exec(`CREATE TABLE IF NOT EXISTS words (id INTEGER PRIMARY KEY, word TEXT);`) + if err != nil { + log.Fatal(err) + } + + // Insert top English words into the database + tx, err := db.Begin() + if err != nil { + log.Fatal(err) + } + + stmt, err := tx.Prepare("INSERT INTO words(word) VALUES(?)") + if err != nil { + log.Fatal(err) + } + defer stmt.Close() + + for _, word := range topEnglishWords { + _, err = stmt.Exec(word) + if err != nil { + log.Fatal(err) + } + } + + // Commit the transaction + tx.Commit() + + fmt.Println("Top English words inserted into the database.") + + // Read the contents of the american-english file + filePath := "/usr/share/dict/american-english" + content, err := ioutil.ReadFile(filePath) + if err != nil { + log.Fatal(err) + } + + // Split content into words + words := strings.Fields(string(content)) + + // Insert american-english words into the database + tx, err = db.Begin() + if err != nil { + log.Fatal(err) + } + + stmt, err = tx.Prepare("INSERT INTO words(word) VALUES(?)") + if err != nil { + log.Fatal(err) + } + defer stmt.Close() + + for _, word := range words { + _, err = stmt.Exec(word) + if err != nil { + log.Fatal(err) + } + } + + // Commit the transaction + tx.Commit() + + fmt.Println("American-English words inserted into the database.") +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7993320 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module xorWords + +go 1.20 + +require github.com/mattn/go-sqlite3 v1.14.19 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3042612 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= +github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= diff --git a/readData.go b/readData.go new file mode 100644 index 0000000..4b62c67 --- /dev/null +++ b/readData.go @@ -0,0 +1,130 @@ +package main + +import ( + "database/sql" + "flag" + "bufio" + "fmt" + "log" + "strings" + "strconv" + "os" + + _ "github.com/mattn/go-sqlite3" +) + +func containsSymbol(input string, symbols []string) bool { + for _, symbol := range symbols { + if strings.Contains(input, symbol) { + return true + } + } + return false +} + +func main() { + // Define a command-line flag for the filename + filenamePtr := flag.String("file", "results.txt", "Name of the file to write results to") + flag.Parse() + + // Open the SQLite3 database file + db, err := sql.Open("sqlite3", "./english_words.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + // Open the file + file, err := os.Open(*filenamePtr) + if err != nil { + fmt.Println("Error opening file:", err) + return + } + defer file.Close() + + symbols := []string{ + ".", ",", "!", ";", "?", "(", ")", "'", "\"", + } + + // Create a scanner to read the file line by line + scanner := bufio.NewScanner(file) + + // Loop through each line in the file + for scanner.Scan() { + line := scanner.Text() + + // Split the line by spaces + parts := strings.Fields(line) + last := "" + // Process the parsed values (assuming each line has a specific structure) + for _, part := range parts { + if strings.Contains(part, "_") { + result := strings.Replace(part, "_", "", -1) + input := decompressRLE(xorBy13(result)) + if containsSymbol(input, symbols) { + last = strings.TrimRight(last, " ") + fmt.Sprintf("%s ", input) + } else { + last = last + fmt.Sprintf("%s ", input) + } + } else { + query := "SELECT word FROM words WHERE id = ?" + rows, err := db.Query(query, part) + if err != nil { + log.Fatal(err) + } + defer rows.Close() + if rows.Next() { + var word string + err = rows.Scan(&word) + if err != nil { + log.Fatal(err) + } + if containsSymbol(word, symbols) { + last = strings.TrimRight(last, " ") + fmt.Sprintf("%s ", word) + } else { + last = last + fmt.Sprintf("%s ", word) + } + } + } + } + fmt.Println(last) + } + + // Check for errors during scanning + if err := scanner.Err(); err != nil { + fmt.Println("Error reading file:", err) + } +} + +// decompressRLE decompresses a string that has been Run-Length Encoded +func decompressRLE(compressed string) string { + result := "" + + for i := 0; i < len(compressed); i += 2 { + char := compressed[i] + count, err := strconv.Atoi(string(compressed[i+1])) + if err != nil { + // Handle error if conversion fails + fmt.Println("Error converting count to integer:", err) + return "" + } + + // Repeat the character count times in the result + for j := 0; j < count; j++ { + result += string(char) + } + } + + return result +} + +func xorBy13(input string) string { + var result strings.Builder + + for _, char := range input { + xored := char ^ 13 + result.WriteRune(xored) + } + + return result.String() +} diff --git a/writeData.go b/writeData.go new file mode 100644 index 0000000..b6486ef --- /dev/null +++ b/writeData.go @@ -0,0 +1,155 @@ +package main + +import ( + "database/sql" + "flag" + "fmt" + "log" + "strings" + "os" + "strconv" + + _ "github.com/mattn/go-sqlite3" +) + +var symbols = []string{ + ".", ",", "!", ";", "?", "(", ")", "'", "\"", +} + + +func main() { + // Define a command-line flag for the filename + filenamePtr := flag.String("file", "results.txt", "Name of the file to write results to") + flag.Parse() + + // Open the SQLite3 database file + db, err := sql.Open("sqlite3", "./english_words.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + for { + + // Get user input for the test query + fmt.Print("Enter keyword: ") + var searchTerm string + fmt.Scanln(&searchTerm) + + // Exit the loop if Enter key is pressed without entering a search term + if searchTerm == "" { + break + } + + // Execute the first query with case-sensitive like + query := "SELECT id FROM words WHERE word COLLATE BINARY = ?" + rows, err := db.Query(query, searchTerm) + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + // If no results, try case-insensitive like + if !rows.Next() { + rows.Close() // Close the previous result set before executing a new query + + // Execute the second query with case-insensitive like + query = "SELECT id FROM words WHERE LOWER(word) LIKE ?" + rows, err = db.Query(query, strings.ToLower(searchTerm)) + if err != nil { + log.Fatal(err) + } + defer rows.Close() + if rows.Next() { + // Process the results + fmt.Println("Results for case-insensitive LIKE:") + writeResultsToFile(*filenamePtr, rows) + } else { + if strings.Contains(searchTerm, "*") { + result := strings.Replace(searchTerm, "*", "", -1) + writeDataToFile(*filenamePtr, xorBy13(compressRLE(result))) + } else { + fmt.Println("Not found! Please retype and add an * at the end to save") + } + + } + } else { + // Process the results + fmt.Println("Results for case-sensitive LIKE:") + writeResultsToFile(*filenamePtr, rows) + } + } +} + +func writeDataToFile(filename string, data string) { + file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + result := fmt.Sprintf("_%s ", data) + _, err = file.WriteString(result) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Added to %s\n", filename) +} + +func writeResultsToFile(filename string, rows *sql.Rows) { + file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + var id int + err = rows.Scan(&id) + if err != nil { + log.Fatal(err) + } + fmt.Printf("ID=%d\n", id) + + result := fmt.Sprintf("%d ", id) + _, err = file.WriteString(result) + if err != nil { + log.Fatal(err) + } + + if err := rows.Err(); err != nil { + log.Fatal(err) + } + fmt.Printf("Results written to %s\n", filename) +} + +func xorBy13(input string) string { + var result strings.Builder + + for _, char := range input { + xored := char ^ 13 + result.WriteRune(xored) + } + + return result.String() +} + +// compressRLE compresses a string using Run-Length Encoding +func compressRLE(input string) string { + result := "" + count := 1 + + for i := 1; i < len(input); i++ { + if input[i-1] == input[i] { + count++ + } else { + result += string(input[i-1]) + strconv.Itoa(count) + count = 1 + } + } + + // Add the last character and its count + result += string(input[len(input)-1]) + strconv.Itoa(count) + + return result +}