Intro
In Part 1, I wrote a function that encodes a string of text in a Caesar cipher.
In the second part of my series, I'm writing some files that decode an English string encoded with a Caesar cipher!
Getting Started
To start, I realized that my program would need to know how to encipher a string in order to decipher it, much the same as human cryptographers start by understanding how something is en-ciphered before de-ciphering.
So I popped the function from part 1 of my blog post into utils.js
. Then, in app.js
, I imported it:
const { caesarShift } = require('./utils')
Now, since in my enciphering function I only allowed 26 possibilities (technically 52 counting the negative shifts, but those are also technically the same as the positive ones since I 'wrapped around'), I could generate them by calling this utility like so:
function loopPossibilites(text) {
let arrayOfPossibilities = []
for (let i = 0; i <= 26; i++) {
arrayOfPossibilities.push(caesarShift(text, i))
}
return arrayOfPossibilities
}
This function returns:
[
'ifmmp', 'jgnnq', 'khoor',
'lipps', 'mjqqt', 'nkrru',
'olssv', 'pmttw', 'qnuux',
'rovvy', 'spwwz', 'tqxx',
'uryya', 'vszzb', 'wtc',
'xuaad', 'yvbbe', 'zwccf',
'xddg', 'ayeeh', 'bzffi',
'cggj', 'dahhk', 'ebiil',
'fcjjm', 'gdkkn', 'hello'
]
Now it is obvious from looking at this small array that 'hello' is the answer to the encoded string I passed, but what if the texts were longer and drifted off my screen? What if I had a lot to decode and my eyes were tired?
It was time to introduce an API.
The API
I ended up using the DetectLanguage API, which has a super convenient node implementation.
const DetectLanguage = require('detectlanguage')
const detectlanguage = new DetectLanguage(process.env.APIKEY)
Here is how I used it in my next function:
async function detectMeaning(text) {
arrayOfPossibleMeanings = []
let possibilities = loopPossibilites(text)
for (let i = 0; i <= possibilities.length; i++) {
try {
await detectlanguage
.detect(possibilities[i])
.then(function (result) {
if (
result[0] &&
result[0].language === 'en' &&
result[0].isReliable === true
) {
arrayOfPossibleMeanings.push(possibilities[i])
}
})
} catch (e) {
console.log('ERROR', e)
}
}
return arrayOfPossibleMeanings
}
As you can see, first I call loopPossibilites
, then loop through the array that returns. On each string I call the detectlanguage
API method. If the result comes up as both English and reliable, I push it into a results array, which I then return.
This ensures that this value:
detectMeaning('ifmmp').then((data) => {
console.log(data)
})
comes up in my terminal as
['hello']
.
Hurray! I did it! 🥳
Areas of improvement
There are a couple areas of improvement. For one, my error is vague:
} catch (e) {
console.log('ERROR', e)
}
Creating a higher level of granularity here is a goal for me.
The other is that since my function makes an API call for each string in my array of possibilities, the answer comes back very slowly. There is an option for making a batch call in the API but it makes a separate call for each string so it doesn't really matter.
If you've got ideas for me to improve these areas, I'd love to hear them!
PSSST -> Here's the original repo.
:) Lucia
Top comments (0)