Published
Edited
May 15, 2019
Insert cell
md`# Fallen Transponder Redux

I originally has some trouble with this because my data was wrong... However, I figured out the proper pattern and fixed the typos in the original text....

RENDEZVOUS
${transponder}

## Identify Keys
There are groups of characters that are either \`(CCnC)\` (where \`C\` represents a letter and \`n\` represents a number) or \`(nnnC)\`... Specifically \`(00nC)\`. I bet groups of the latter represent our key. Let's identify them by using the number that comes before the letter to modify the ascii code represented by the letter by \`-n\`

<pre style="font-family: monospace">
${Object.keys(transponderKeyTest).map((key,idx) => `${idx}. ${key}: ${transponderKeyTest[key]}`).join('<br/>')}
</pre>

## Seems like the right track
We have -most- of the letters used to spell RENDEZVOUS. Let's do all of the letters from A-Z this way. We'll use \`-5\` as the modifier because all of the "key groups" have 5 has the modifier.

<pre style="font-family: monospace">
${Object.keys(transponderKeys).map((key,idx) => `${idx}. ${key}: ${transponderKeys[key]}`).join('<br/>')}
</pre>


## Replace Encrypted Text with Ciphers
<pre style="font-family: monospace">
${decrypted}
</pre>

## Hmmm... Not Quite Right
Perhaps the pairs of \`nC\` in the \`(CCnC)\` groups should be modified as well. The first one I see is now \`(ZV3L)\`. The word should be \`rendeZVOus\` but is currently \`rendeZVLus\`. But, it turns out \`L+3 = O\`, so let's try that replacement.

<pre style="font-family: monospace">
${doubleDecrypted}
</pre>


Then modify the \`((3000)cn)\` groups to add \`number of spaces = n\` and \`c.toUpperCase() + 3\`:
<pre style="font-family: monospace">
${tripleDecrypted}
</pre>

Finally, convert all remaining \`(3000)\` groups to a single space:
<pre style="font-family: monospace">
${quadDecrypted}
</pre>


## Split into lines

<pre style="font-family: monospace">
${lines.join('\n')}
</pre>


It seems to be making a pictogram of some sort, but my decoding still isn't 100% correct...
`

Insert cell
md`${transponder}`
Insert cell
transponderKeyTest = {
const keyrgx = /\(00(\d)([A-Z])/g
const keys = []
let matches
while((matches = keyrgx.exec(transponder)) !== null) {
const original = matches[2]
const modifier = Number(matches[1])
const cipher = String.fromCharCode(original.charCodeAt(0) - modifier)
keys[original] = cipher
}
return keys
}
Insert cell
transponderKeys = sequence(26, x => String.fromCharCode(x+65)).reduce((agg, char) => ({...agg, [char]: String.fromCharCode((char.charCodeAt(0) - 65 + 21) % 26 + 65)}),{})
Insert cell
decrypted = transponder.split('').map(
char => !!transponderKeys[char] ? transponderKeys[char] : char
).join('')
Insert cell
doubleDecrypted = {
// replace beginning and end
let pairsrgx = /(\d)([A-Z])/g
const pairs = []
let matches
while((matches = pairsrgx.exec(decrypted)) !== null) {
pairs.push({mod: Number(matches[1]), char: matches[2]})
}

const ciphers = pairs.reduce((agg, pair) => {
const charCode = pair.char.charCodeAt(0)
const charNum = charCode - 65
return {...agg, [`${pair.mod}${pair.char}`]: String.fromCharCode((charNum + pair.mod) % 26 + 65)}
},{})
//return ciphers
return Object.keys(ciphers).reduce((str, key) => str.replace(new RegExp(`${key}`,'g'), ciphers[key]), decrypted)
}
Insert cell
tripleDecrypted = {
const startgrouprgx = /(\d{1,2})\(\(3000\)([a-z])(\d+)\)/g
const grouprgx = /\(\(3000\)([a-z])(\d+)\)/g
const startgroups = new Map()
const endgroups = new Map()
let matches
while((matches = startgrouprgx.exec(doubleDecrypted)) !== null) {
startgroups.set(matches[0].replace(/\(/g,'\\(').replace(/\)/g,'\\)'),{char: matches[2].toUpperCase(), spaces: Number(matches[3]), linenum: matches[1] })
}
const startgroupKeys = Array.from(startgroups.keys())
const startgroupsreplaced = startgroupKeys.reduce((str, key) => {
console.log('key:', key)
const group = startgroups.get(key)
console.log('group:', group)
const keyrgx = new RegExp(key, 'g')
const {linenum} = group
const spaces = sequence(group.spaces, _ => ' ').join('')
const char = String.fromCharCode(group.char.charCodeAt(0) + 3)
const replaceWith = `${spaces}${char}`
const newstr = str.replace(keyrgx, `${linenum}:${spaces}${char}`)
console.log(newstr)
return newstr
}, doubleDecrypted)
while((matches = grouprgx.exec(doubleDecrypted)) !== null) {
endgroups.set(matches[0].replace(/\(/g,'\\(').replace(/\)/g,'\\)'),{char: matches[1].toUpperCase(), spaces: Number(matches[2]) })
}
const endgroupKeys = Array.from(endgroups.keys())
const endgroupsreplaced = endgroupKeys.reduce((str, key) => {
console.log('key:', key)
const group = endgroups.get(key)
console.log('group:', group)
const keyrgx = new RegExp(key, 'g')
const spaces = sequence(group.spaces, _ => ' ').join('')
const char = String.fromCharCode(group.char.charCodeAt(0) + 3)
const replaceWith = `${spaces}${char}`
const newstr = str.replace(keyrgx, `${char}${spaces}`)
console.log(newstr)
return newstr
}, startgroupsreplaced)
return endgroupsreplaced.replace(/3000/g,' ')

// const groupKeys = Array.from(groups.keys())
// console.log('groupKeys:', groupKeys)
// const nextstr = groupKeys.reduce((str, key) => {
// console.log('key:', key)
// const group = groups.get(key)
// console.log('group:', group)
// const keyrgx = new RegExp(key, 'g')
// const spaces = sequence(group.spaces, _ => ' ').join('')
// const char = String.fromCharCode(group.char.charCodeAt(0) + 3)
// const replaceWith = `${spaces}${char}`
// const newstr = str.replace(keyrgx, `${spaces}${char}`)
// console.log(newstr)
// return newstr
// }, doubleDecrypted)
// return nextstr
}
Insert cell
quadDecrypted = {
const spacergx = /3000/g
return tripleDecrypted.replace(spacergx, ' ')
}
Insert cell
linerxp = /\d{1,2}:/g
Insert cell
lines = quadDecrypted.split(linerxp).slice(1)

Insert cell
transponder = `1((3000)o20)(JS0I)((3000)b2)(EA3Q)((3000)r20)2((3000)p18)(WJ0S)(3000)(IJ0E)(3000)(AT3W)(3000)(XW3G)((3000)k18)3((3000)a16)(JE0A)(3000)(TZ0X)(3000)(WJ0S)(IJ3B)(3000)(AT3W)(3000)(XW3G)((3000)k16)4((3000)a14)(JE0A)(3000)(TZ0X)(3000)(WJ0S)((3000)a4)(JE3X)(3000)(TZ3U)(3000)(WJ3P)((3000)a14)5((3000)b12)(EA0T)(3000)(ZX0W)((3000)b6)(00Q7)((3000)a6)(JE3X)(3000)(TZ3U)((3000)o12)6((3000)b10)(SI0J)(3000)(EAOT)((3000)r4)(XW0J)(SI3G)((3000)w4)(AT0Z)(XW3G)((3000)k3)(IJ3B)(3000)(AT3W)((3000)p10)7((3000)o8)(JS0I)(3000)(JE0A)((3000)l4)(ZX0W)(JS3F)(JE3X)(3000)(TZ3U)(WJ0S)(3000)(IJ0E)(AT0Z)(XW3G)((3000)k3)(IJ3B)(3000)(AT3W)((3000)p8)8((3000)o6)(JS0I)(3000)(JE0A)((3000)l4)(ZX0W)(005J)(005S)(005I)(005J)(EA3Q)(ZX3T)(3000)(JS0I)(JE0A)(005T)(005Z)(005X)(005W)(JS3F)((3000)b4)(EA3Q)(3000)(ZX3T)((3000)b6)9((3000)k4)(IJ0E)(3000)(AT0Z)((3000)p12)(WJOS)(005I)(005J)(EA3Q)((3000)02)(XW3G)(3000)(SI3G)((3000)w4)10((3000)s5)(TZ0X)((3000)o32)(JS3F)((3000)b5)`
Insert cell
sequence = (count, fn) => [...Array(count).keys()].map((x, i, arr) => fn(i, arr))
Insert cell
stringify = x => x instanceof Array ? '```' + x.join('\n\n') + '```' : JSON.stringify(x, null, 2)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more