Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Created May 6, 2017 13:58
Show Gist options
  • Select an option

  • Save gvergnaud/469a5245ef84de4ebcaf116054b44eee to your computer and use it in GitHub Desktop.

Select an option

Save gvergnaud/469a5245ef84de4ebcaf116054b44eee to your computer and use it in GitHub Desktop.
// crack the ceasar code by minimazing the distance between english language letter
// occurrence and all the letter occurrence of all the possible shifts of a message.
const englishLetterOccurrence = [ 8.2, 1.5, 2.8, 4.3, 12.7, 2.2, 2.0, 6.1, 7.0, 0.2, 0.8, 4.0, 2.4, 6.7, 7.5, 1.9, 0.1, 6.0, 6.3, 9.1, 2.8, 1.0, 2.4, 0.2, 2.0, 0.1 ]
const letters = 'abcdefghijklmnopqrstuvwxyz'.split('')
const letterOccurrence = str =>
letters
.map(c => (str.match(new RegExp(c, 'gi')) || []).length)
.map(n => 100 * n / str.length)
const range = (start, end) => {
const xs = []
for (let i = start; i <= end; i++) xs.push(i)
return xs
}
const drop = (n, xs) => xs.slice(n)
const take = (n, xs) => xs.slice(0, n)
const rotate = (n, xs) => {
return drop(n, xs).concat(take(n, xs))
}
const sum = xs => xs.reduce((x, y) => x + y, 0)
const zipWith = (xs, ys, zipper) =>
xs.length < ys.length
? xs.map((x, i) => zipper(x, ys[i]))
: ys.map((y, i) => zipper(xs[i], y))
const getDistance = (xs, ys) =>
Math.sqrt(sum(zipWith(xs, ys, (x, y) => (x - y) ** 2)))
const encode = (n, str) => str
.split('')
.map(x => letters.includes(x.toLowerCase())
? letters[(letters.indexOf(x.toLowerCase()) + n) % letters.length]
: x)
.join('')
const unCeasar = str => {
const occurence = letterOccurrence(str)
const shiftScores = range(0, englishLetterOccurrence.length - 1)
.map(n => getDistance(rotate(n, occurrence), englishLetterOccurrence))
const shiftIndex = shiftScores.indexOf(Math.min(...shiftScores))
// we found out that the alphabet was shifted `shiftIndex` times on the right
// so we have to negate this to decode the message.
return encode(-shiftIndex, str)
}
const secretMessage = `dv dqb vfudeeoh sodbhu nqrzv, lw lv pxfk hdvlhu wr frph xs zlwk zrugv wkdw ehjlq zlwk d sduwlfxodu ohwwhu wkdq wr ilqg zrugv wkdw kdyh wkh vdph ohwwhu lq wkh wklug srvlwlrq. wklv lv wuxh iru hyhub ohwwhu ri wkh doskdehw. zh wkhuhiruh hashfwhg uhvsrqghqwv wr hadjjhudwh wkh iuhtxhqfb ri ohwwhuv dsshdulqj lq wkh iluvw srvlwlrq—hyhq wkrvh ohwwhuv (vxfk dv n, o, q, u, y) zklfk lq idfw rffxu pruh iuhtxhqwob lq wkh wklug srvlwlrq. khuh djdlq, wkh uholdqfh rq d khxulvwlf surgxfhv d suhglfwdeoh eldv lq mxgjphqwv. iru hadpsoh, l uhfhqwob fdph wr grxew pb orqj-khog lpsuhvvlrq wkdw dgxowhub lv pruh frpprq dprqj srolwlfldqv wkdq dprqj skbvlfldqv ru odzbhuv. l kdg hyhq frph xs zlwk hasodqdwlrqv iru wkdw “idfw,” lqfoxglqj wkh dskurglvldf hiihfw ri srzhu dqg wkh whpswdwlrqv ri olih dzdb iurp krph. l hyhqwxdoob uhdolchg wkdw wkh wudqvjuhvvlrqv ri srolwlfldqv duh pxfk pruh olnhob wr eh uhsruwhg wkdq wkh wudqvjuhvvlrqv ri odzbhuv dqg grfwruv. pb lqwxlwlyh lpsuhvvlrq frxog eh gxh hqwluhob wr mrxuqdolvwv’ fkrlfhv ri wrslfv dqg wr pb uholdqfh rq wkh dydlodelolwb khxulvwlf. dprv dqg l vshqw vhyhudo bhduv vwxgblqj dqg grfxphqwlqj eldvhv ri lqwxlwlyh wklqnlqj lq ydulrxv wdvnv—dvvljqlqj suredelolwlhv wr hyhqwv, iruhfdvwlqj wkh ixwxuh, dvvhvvlqj kbsrwkhvhv, dqg hvwlpdwlqj iuhtxhqflhv. lq wkh iliwk bhdu ri rxu frooderudwlrq, zh suhvhqwhg rxu pdlq ilqglqjv lq vflhqfh pdjdclqh, d sxeolfdwlrq uhdg eb vfkroduv lq pdqb glvflsolqhv. wkh duwlfoh (zklfk lv uhsurgxfhg lq ixoo dw wkh hqg ri wklv errn) zdv wlwohg “mxgjphqw xqghu xqfhuwdlqwb: khxulvwlfv dqg eldvhv.” lw ghvfulehg wkh vlpsoliblqj vkruwfxwv ri lqwxlwlyh wklqnlqj dqg hasodlqhg vrph 20 eldvhv dv pdqlihvwdwlrqv ri wkhvh khxulvwlfv—dqg dovr dv ghprqvwudwlrqv ri wkh uroh ri khxulvwlfv lq mxgjphqw.`
console.log(unCeasar(secretMessage))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment