.vigenère was cool

Well… Actually Giovan Battista Bellaso was cool because he invented the Vigenère cipher but wasn’t credited for his discovery by many. All around Bellaso seems to be a fairly talented person (Vigenère too) but one day he devised a method to encipher a message which was quite successful.

As a developer I often feel like I have tangential experience in fields I know little about. When people would tell me “Vigenère cipher is broken” I would blindly repeat what they said; usually followed by the explanation common in Hollywood movies describing statistical analysis of cipher text to guess keys. Cryptography was a field which I felt I understood until researching earlier non-machine cryptography.

One cipher which stood out was Bellaso’s cipher as it is not susceptible to using common words or characters in order to decode the message. The only way I can find to decrypt messages encrypted with Bellaso’s cipher is to either have the key or know the language the message is written in and know the key length. If I know the language and the key length of the message then I have enough intelligence to steal the key too.

I am not much of a historian so in order for me to enjoy the work which was done I implemented a Vigenère cipher in coffeescript and here it is. It needs some sort of interactivity.

  cipher = (key, message, cipher) ->
  if containsInvalidKeyCharacters(key) or containsInvalidMessageCharacters(message)
    throw "Invalid characters in key or message."

  fullKey = matchKeyLengthToMessage key, message.length

  alphabetSize = 26

  fullKeyCharacterCodes = fullKey.split("").map (character) -> character.charCodeAt 0
  fullMessageCharacterCodes = message.split("").map (character) -> character.charCodeAt 0

  cipherCharacterCodes = for keyCharacterCode, i in fullKeyCharacterCodes
    messageAlphabetCharacterCode = convertUnicodeCharacterCodeToAlphabet fullMessageCharacterCodes[i]
    keyAlphabetCharacterCode = convertUnicodeCharacterCodeToAlphabet keyCharacterCode

    cipherAlphabetCharacter = cipher(
      keyAlphabetCharacterCode,
      messageAlphabetCharacterCode,
      alphabetSize)

    # The last character Z will match to be 0 and needs to be set
    # as the last character.
    # TODO I am positive there is a workaround for this
    if cipherAlphabetCharacter is 0
      cipherAlphabetCharacter = alphabetSize

    cipherCharacter = convertAlphabetCharacterCodeToUnicode cipherAlphabetCharacter

  String.fromCharCode.apply null, cipherCharacterCodes

# The Character Codes in Javascript UNICODE do not match to 1-26 for A-Z so this will offset the character codes back.
# This translates to A in UNICODE 65
convertUnicodeCharacterCodeToAlphabet = (code, unicodeOffset=64) ->
  code - unicodeOffset

convertAlphabetCharacterCodeToUnicode = (code, unicodeOffset=64) ->
  code + unicodeOffset

containsInvalidKeyCharacters = (string) ->
  /[^A-Z]/.test(string)

containsInvalidMessageCharacters = (string) ->
  containsInvalidKeyCharacters string

matchKeyLengthToMessage = (key, messageLength) ->
  keyCharacters = key.split("")

  if keyCharacters.length is 0
    throw "Key is blank."

  if messageLength is 0
    throw "Message is empty."

  fullKeyCharacters = for i in [0..messageLength-1]
    keyCharacters[i % keyCharacters.length]

  fullKeyCharacters.join ""


#############################################
##              Actual Code                ##
#############################################
key = "CRYPTO"
message = "WHATANICEDAYTODAY"

vigenèreEncrypt = (key, message) ->
  cipher key, message, (keyCharacterCode, messageCharacterCode, alphabetSize) ->
    (keyCharacterCode + messageCharacterCode) % alphabetSize

vigenèreDecrypt = (key, encryptedMessage) ->
  cipher key, encryptedMessage, (keyCharacterCode, messageCharacterCode, alphabetSize) ->
    (messageCharacterCode - keyCharacterCode + alphabetSize) % alphabetSize

encryptedMessage = vigenèreEncrypt(key, message)
decryptedMessage = vigenèreDecrypt(key, encryptedMessage)

console.log """
  Encrypting #{message} with a key of #{key} using Vigenère cipher.
  Encrypted message is #{ encryptedMessage }.
  Decrypted message is #{ decryptedMessage }.
"""


#############################################
##                 Tests                   ##
#############################################
runTests = ->
  assert = require 'assert'

  key = "CRYPTO"
  message = "WHATANICEDAYTODAY"

  messageLength = message.split("").length

  assert.equal vigenèreEncrypt(key, message), "ZZZJUCLUDTUNWGCQS"
  assert.equal vigenèreEncrypt("ABC", "ABC"), "BDF"
  assert.equal vigenèreEncrypt("ABC", "A"), "B"
  assert.equal vigenèreEncrypt("Z", "ZAZ"), "ZAZ" #Interesting
  assert.equal vigenèreEncrypt("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), "BDFHJLNPRTVXZBDFHJLNPRTVXZ"
  assert.equal vigenèreEncrypt("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ZZZZZZZZZZZZZZZZZZZZZZZZZZ"), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  assert.equal vigenèreDecrypt(key, "ZZZJUCLUDTUNWGCQS"), message
  assert.equal vigenèreDecrypt("ABC", "BDF"), "ABC"
  assert.equal vigenèreDecrypt("ABC", "B"), "A"
  assert.equal vigenèreDecrypt("Z", "ZAZ"), "ZAZ" #Interesting
  assert.equal vigenèreDecrypt("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "BDFHJLNPRTVXZBDFHJLNPRTVXZ"), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  assert.equal vigenèreDecrypt("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), "ZZZZZZZZZZZZZZZZZZZZZZZZZZ" # Hehe sweet

  assert.equal matchKeyLengthToMessage(key, messageLength), "CRYPTOCRYPTOCRYPT", "Oops, key length mismatch"
  assert.throws (-> matchKeyLengthToMessage(key, 0)), "Blank Message"
  assert.throws (-> matchKeyLengthToMessage("", messageLength)), "Blank Key"

  assert containsInvalidKeyCharacters("123A")
  assert not containsInvalidKeyCharacters("ABC")

  assert containsInvalidMessageCharacters("123A")
  assert not containsInvalidMessageCharacters("ABC")

  assert.equal convertUnicodeCharacterCodeToAlphabet(65), 1
  assert.equal convertAlphabetCharacterCodeToUnicode(1), 65

  assert.doesNotThrow (-> cipher(key, message, ->))
  assert.throws (-> cipher("", message, -> )), "Invalid Key"
  assert.throws (-> cipher(key, "", -> )), "Invalid Message"
  assert.throws (-> cipher("BLA2", message, ->)), "Invalid Characters Key"
  assert.throws (-> cipher(key, 0, ->)), "Invalid Characters Message"

runTests()

Interesting note, UTF8 in filenames or code messes up Github.

.ArnoldC meets Pascal

ArnoldC is an incredibly fun esoteric language based on quotes from Arnold Schwarzenegger movies. The keywords are easy to comprehend but putting them together in order to make anything more than a “Hello World!” example can be frustrating.

I tried to build Pascal’s Triangle in ArnoldC in order to investigate how a language constructed of quotes might look with a complete program. My hope was that I would come out with a scene from a movie in the source code. Unfortunately I did not end up having a script and instead found that it now looks like any other programming language. When I start to look at it my brain begins to parse it and soon I am thinking about ArnoldC code as if it were code I actually use for real projects!!!

Without any commercial breaks, here is Pascal’s Triangle in ArnoldC.

  IT'S SHOWTIME
  TALK TO THE HAND "HOW DEEP YOU WANT THIS TRIANGLE?"
  HEY CHRISTMAS TREE TRIANGLEDEPTH
    YOU SET US UP 0
  GET YOUR ASS TO MARS TRIANGLEDEPTH
    DO IT NOW
    I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY

  DO IT NOW TRIANGLE TRIANGLEDEPTH

  TALK TO THE HAND "HERE YOU GO PASCAL"
YOU HAVE BEEN TERMINATED

LISTEN TO ME VERY CAREFULLY TRIANGLE
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE DEPTH

  HEY CHRISTMAS TREE TRIANGLEDONE
    YOU SET US UP @NO PROBLEMO
  HEY CHRISTMAS TREE ROWNUM
    YOU SET US UP 0

  STICK AROUND TRIANGLEDONE
    DO IT NOW ROWS ROWNUM

    GET TO THE CHOPPER ROWNUM
      HERE IS MY INVITATION ROWNUM
      GET UP 1
    ENOUGH TALK

    GET TO THE CHOPPER TRIANGLEDONE
      HERE IS MY INVITATION DEPTH
      LET OFF SOME STEAM BENNET ROWNUM
    ENOUGH TALK
  CHILL
HASTA LA VISTA, BABY

LISTEN TO ME VERY CAREFULLY ROWS
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE ROWNUM
  HEY CHRISTMAS TREE ROWDONE
    YOU SET US UP @NO PROBLEMO
  HEY CHRISTMAS TREE COLNUM
    YOU SET US UP 0

  HEY CHRISTMAS TREE NEXTROW
    YOU SET US UP ROWNUM

  GET TO THE CHOPPER NEXTROW
    HERE IS MY INVITATION NEXTROW
    GET UP 1
  ENOUGH TALK

  STICK AROUND ROWDONE
    DO IT NOW COLS COLNUM ROWNUM

    GET TO THE CHOPPER COLNUM
      HERE IS MY INVITATION COLNUM
      GET UP 1
    ENOUGH TALK

    GET TO THE CHOPPER ROWDONE
      HERE IS MY INVITATION NEXTROW
      LET OFF SOME STEAM BENNET COLNUM
    ENOUGH TALK
  CHILL
HASTA LA VISTA, BABY

LISTEN TO ME VERY CAREFULLY COLS
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE COLNUM
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE ROWNUM

  HEY CHRISTMAS TREE COLDONE
    YOU SET US UP @NO PROBLEMO
  HEY CHRISTMAS TREE OLDCOL
    YOU SET US UP 1

  HEY CHRISTMAS TREE NEXTCOL
    YOU SET US UP COLNUM

  GET TO THE CHOPPER NEXTCOL
    HERE IS MY INVITATION NEXTCOL
    GET UP 1
  ENOUGH TALK

  HEY CHRISTMAS TREE CURRENTSUM
    YOU SET US UP 1

  GET TO THE CHOPPER COLDONE
    HERE IS MY INVITATION NEXTCOL
    LET OFF SOME STEAM BENNET OLDCOL
  ENOUGH TALK

  STICK AROUND COLDONE
    GET YOUR ASS TO MARS CURRENTSUM
      DO IT NOW ROW CURRENTSUM OLDCOL ROWNUM

    GET TO THE CHOPPER OLDCOL
      HERE IS MY INVITATION OLDCOL
      GET UP 1
    ENOUGH TALK

    GET TO THE CHOPPER COLDONE
      HERE IS MY INVITATION NEXTCOL
      LET OFF SOME STEAM BENNET OLDCOL
    ENOUGH TALK
  CHILL

  TALK TO THE HAND CURRENTSUM
HASTA LA VISTA, BABY

LISTEN TO ME VERY CAREFULLY ROW
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE CURRENTSUM
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE COLUMNNUM
  I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE ROWNUM

  GIVE THESE PEOPLE AIR

  HEY CHRISTMAS TREE NEWSUM
    YOU SET US UP 0

  HEY CHRISTMAS TREE COLROWSUM
    YOU SET US UP 0

  GET TO THE CHOPPER COLROWSUM
    HERE IS MY INVITATION ROWNUM
    GET DOWN COLUMNNUM
    GET UP 1
  ENOUGH TALK

  GET TO THE CHOPPER NEWSUM
    HERE IS MY INVITATION CURRENTSUM
    YOU'RE FIRED COLROWSUM
    HE HAD TO SPLIT COLUMNNUM
  ENOUGH TALK

  I'LL BE BACK NEWSUM
HASTA LA VISTA, BABY

“GET TO THE CHOPPER ROWNUM” – That Code

.dogescript game of life

A dogescript version of Conway's Game of Life. Based on Mfoo's work. It is pretty basic but fun to write in doge.

This is the dogescript which made it, or look dogescript life.

Iteration: 0

Click a cell on the map to manually toggle it.

.Some Code

quiet
  # Conway's Game of Life implementation in DogeScript.
  # Author: Erik Erwitt (e3) <erike@cpan.org>
  # Original Author: Martin Foot <https://github.com/mfoo/CoffeeScript-Game-Of-Life>
  # License: Do what you want.
loud

very canvas is $('#conway')[0]
very iterationCount is 0

shh Specify the width and height of the square used to draw the entities.
very entitySize is 10

very entitiesX is plz Math.ceil with canvas.width/entitySize
very entitiesY is plz Math.ceil with canvas.height/entitySize

shh The number of entities in our board.
very numEntities is entitiesX * entitiesY

shh Store for the JavaScript setInterval timerID for the 'play' functionality.
very timerID is 0

shh A single dimensional array to store all the entities. Default value random.
shh Note: uses row-major ordering
very entities is new Array with numEntities
very newEntities is new Array with numEntities

shh This contains the coordinates to access the 8 surrounding neighbours by means
shh of an offset in a one-dimensional array.
very grid is [-1+-1*entitiesX,-1*entitiesX,1+-1*entitiesX,-1,1,-1+entitiesX,entitiesX,1+entitiesX]

shh Initialise the board to random entries (50% chance of being alive or dead).
such initialize
  much very i as 0 next i smaller numEntities next i more 1
    very rand is Math dose random
    entities[i] is Math dose floor with rand+0.5
    newEntities[i] is entities[i];
    iterationCount is 0;
  wow
wow

shh Render the board
such render
  very canvasExist is canvas.getContext
  rly canvasExist
    very ctx is canvas dose getContext with '2d'
    ctx.fillStyle is "white";
    plz ctx.fillRect with 0 0 canvas.width canvas.height
    ctx.fillStyle is "orange";

    much very i as 0 next i smaller numEntities next i more 1
      very x is i%entitiesX
      very y is plz Math.floor with i/entitiesX
      rly entities[i] is 1
        plz ctx.fillRect with entitySize*x entitySize*y entitySize entitySize
      wow
    wow
  wow

  plz $("#iterationNumber").text with iterationCount
wow

quiet
  # A single iteration of Conway's Game of Life. Do not modify the current board
  # (entities). Any changes go into the buffer (newEntities), which is then
  # swapped at the end of the function.
loud
such step
  much very i as 0 next i smaller numEntities-1 next i more 1
    shh Get the number of live neighbours from the previous turn.
    very liveNeighbours is 0

    much very j as 0 next j smaller grid.length next j more 1
      very tile is i+grid[j]
      very x is tile%entitiesX
      very y is plz Math.floor with tile/entitiesX

      shh Wrap around the edge of the board.
      rly x smaller 0
        x is entitiesX+x;
      wow
      rly y smaller 0
        y is entitiesY+y;
      wow
      rly x biggerish entitiesX
        x is entitiesX-x;
      wow
      rly y biggerish entitiesY
        y is entitiesY-y;
      wow

      rly entities[y*entitiesX+x] is 1
        liveNeighbours+=1;
      wow

      newEntities[i] is entities[i];

      shh Any live cell with fewer than two live neighbours dies, as if caused
      shh by under-population.
      rly liveNeighbours smaller 2 and entities[i] is 1
        newEntities[i] is 0;
      wow

      shh Any live cell with two or three live neighbours lives on to the next
      shh generation.
      rly liveNeighbours is 2 or liveNeighbours is 3
        rly entities[i] is 1
          newEntities[i] is 1;
        wow
      wow

      shh Any live cell with more than three live neighbours dies, as if by
      shh overcrowding.
      rly liveNeighbours bigger 3 and entities[i] is 1
        newEntities[i] is 0;
      wow

      shh Any dead cell with exactly three live neighbours becomes a live cell,
      shh as if by reproduction.
      rly liveNeighbours is 3 and entities[i] is 0
        newEntities[i] is 1;
      wow
    wow
  wow

  shh Swap buffers
  very tmp is entities
  entities is newEntities;
  newEntities is tmp;

  iterationCount+=1;
wow

such tick
  plz step
  plz render
wow

shh Allow somebody to click the mouse and toggle the status of a cell on the
shh board.
such toggleEntity much event
  row is Math.floor((event.pageX-$("#conway").offset().left)/entitySize);
  column is Math.floor((event.pageY-$("#conway").offset().top)/entitySize);
  entities[entitiesX*column+row] is 1-entities[entitiesX*column+row];
  plz render
wow

plz initialize
plz render

such playClick
  timerID is plz setInterval with tick 60
wow

such pauseClick
  plz clearInterval with timerID
wow

such conwayClick
  plz toggleEntity with event
wow

such randomEyes
  plz pauseClick
  plz initialize
  plz render
wow

plz $('#play').click with playClick
plz $("#pause").click with pauseClick
plz $("#stepper").click with tick
plz $("#conway").click with conwayClick
plz $("#randomise").click with randomEyes

.The Internet

Please see included instructions.

The Internet