Created
June 10, 2024 12:03
-
-
Save CompeyDev/fae1ca22f46d56713966dbadb020490a to your computer and use it in GitHub Desktop.
Quick lune script to brute force case cipher encoded texts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --> Brute forces some caesar cipher encoded text | |
| local process = require("@lune/process") | |
| local stdio = require("@lune/stdio") | |
| local net = require("@lune/net") | |
| local CHARS = ("abcdefghijklmnopqrstuvwxyz"):split("") | |
| print(`brutus.luau: {process.os}-{process.arch}`) | |
| local ciphertext = process.args[1] or error("usage: ./brutus.luau [CIPHERTEXT]") | |
| local ciphertextChars = ciphertext:split("") | |
| local possiblePlaintexts = {} | |
| for offset = 1, #CHARS do | |
| local shifted = "" | |
| for _, char in ciphertextChars do | |
| -- Our alphabet set is lowercase, so we normalize the input | |
| char = string.lower(char) | |
| -- Check if the character is in our alphabet, if not, we ignore it | |
| local alphabetPos = table.find(CHARS, char) | |
| if not alphabetPos then | |
| shifted ..= char | |
| continue | |
| end | |
| -- Shift the character based on current offset | |
| local shiftedPos = alphabetPos + offset | |
| if shiftedPos > #CHARS then | |
| -- Wrap back to beginning it exceeds the length of the alphabet | |
| shiftedPos = shiftedPos - #CHARS | |
| end | |
| -- Get the character at the shifted position, at push to str | |
| local shiftedChar = CHARS[shiftedPos] | |
| shifted ..= shiftedChar | |
| end | |
| table.insert(possiblePlaintexts, shifted) | |
| end | |
| local toFilter: boolean = stdio.prompt("confirm", "Filter plaintexts that are not in the English dictionary?") | |
| if toFilter then | |
| local filteredPlaintexts = {} | |
| for pos, possiblePlaintext in possiblePlaintexts do | |
| possiblePlaintext = possiblePlaintext:gsub("%p", "") | |
| local words = possiblePlaintext:split(" ") | |
| local wordValidityResults = {} | |
| for wordPos, word in words do | |
| -- One letter words are sometimes valid, but we don't include them | |
| local isValidWord = if #word == 1 | |
| then false | |
| else net.request("https://api.dictionaryapi.dev/api/v2/entries/en/" .. word).ok | |
| wordValidityResults[wordPos] = isValidWord | |
| end | |
| -- If there is at least one valid English word, we consider the plaintext valid | |
| if table.find(wordValidityResults, true) then | |
| table.insert(filteredPlaintexts, possiblePlaintexts[pos]) | |
| end | |
| end | |
| possiblePlaintexts = filteredPlaintexts | |
| end | |
| print("Possible plaintexts:") | |
| print(table.concat(possiblePlaintexts, "\n")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment