# The AMSCO Cipher

AMSCO is an incomplete columnar transposition cipher. A bit to unpack there, but basically that means that you’re putting the message into columns and those columns may not have equal lengths. It was invented by an A.M. Scott in the 19th century, but strangely there is almost nothing online about him.

The AMSCO cipher has two main components. The first is the plain text you wish to encrypt. The second is the numeric key. The key can be a max length of 9 and must contain the numbers 1-n, with n being the length of the key. 1234 and 4132 would both be valid keys, but 1245 would not.

To encrypt text with an AMSCO cipher a table is created with the key as the head and the plain text separated in a specific pattern. It is split in alternating chunks of two and one characters across the rows with the first row starting with two characters and then each row after that alternating between one and two characters. If the key length is even the last chunk size in a row will be equal to the first chunk size in the following row. It is important that the chunk size alternates along the column.

For example, if our key is 4132 and our plain text is “On the other side of the screen, it all looks so easy”:

4 1 3 2
on t he o
t he r si
de o ft h
e sc r ee
ni t al l
l oo k ss
oe a sy

If you look at the structure of that table, you’ll see that not all the columns are of the same length. The chunk size has the above mentioned alternating pattern:

4 1 3 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1

To encrypt the message, you combine text moving down the columns based on the order of the key. You start with the column “1” (the second column in this example), move on to column “2” (the fourth column), and so on.

The original message, when stripped of punctuation and its text is normalized:

ONTHEOTHERSIDEOFTHESCREENITALLLOOKSSOEASY

The encrypted message:

THEOSCTOOAHERFTRALKSYOSIHEELSSONTDEENILOE

As with any transposition cipher, the frequency count and monographic IC will look like that of plain English. Because this is a transposition cipher, knowing the existence of a single word in the original text could allow us to suss out the entire message, because it could reveal the column structure.

Working on creating some proper code to make the cipher actually usable, but this is a working version of it in Javascript. Requires lodash (npm install lodash).

This file contains 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.

 var _ = require("lodash"); var plainText = "On the other side of the screen it all looks so easy"; var key = "4123"; var cipherText = ""; var cols = []; _.each(key.split(""), function(k) { cols.push({ id: Number(k), chunks: [] }); }); // remove any spaces and convert to upper case. Normallizing the text isn't requierd, // but not doing so would leak information about the text being output var compressedText = plainText.replace(/\s+/g, "").toLocaleUpperCase(); var a = 0; // track position in compressedText var i = 0; // column index var row = 0; var chunkSize = 1; var chunk = ""; var cellMap = [[]]; for (var z=0; z 0) { rowCount++; } } else { rowCount = 0; a = 0; // rowCharCount varies by row // even rows, which start with 2 chars: while (a < cipherText.length) { if (rowCount % 2 === 0) { rowCharCount = key.length + Math.ceil(key.length / 2); } else { rowCharCount = key.length + Math.floor(key.length / 2); } a += rowCharCount; rowCount++; } } // now that the ciphertext has been created // let's attempt to decrypt it using the key // the first step is to create a place to put the values var newCols = []; _.each(key.split(""), function(k) { newCols.push({ id: Number(k), chunks: [] }) }); a = 0; i = 1; row = 0; var colKey = 0; while (a < cipherText.length) { colKey = key.indexOf(i); // utilizing the cellMap we built up earlier. This is // just a table of 2,1,2,1,… values that // represent the chunk size structure rowCount = cellMap[colKey].length; chunkSize = cellMap[colKey][row]; // grab the new column column = _.find(newCols, {id : i}); // get the chunk chunk = cipherText.substr(a, chunkSize); // push the chunk column.chunks.push(chunk); a += chunkSize; row++; if (row === rowCount) { row = 0; i++; } } // build the message back up // this will just go through the columns // in proper order, from left to right and then down // and rebuild the original message a = 0; var finalMessage = ""; i = 0; while (finalMessage.length < compressedText.length) { column = newCols[i]; finalMessage += column.chunks.shift(); i++; // move back to the first column if (i === key.length) { i = 0; } } // let's see how we did console.log(compressedText); console.log(cipherText); console.log(finalMessage); if (compressedText === finalMessage) { console.log("Congrats"); } else { console.log("Failed") }

view raw

amsco.js

hosted with ❤ by GitHub

This entry was posted in Ciphers, Crypto and tagged , , , . Bookmark the permalink.