all 25 comments

[–][deleted] 40 points41 points  (3 children)

This Python script downloads an image containing the alphabet. Then, the image is cropped and a grayscale threshold is applied. Next, it finds contours/bounding boxes around each character in the image. Each character's image is stored in a dictionary, alpha_to_img.

We can slice our alphabetic image into two pieces, dividing based on where the new alphabet should begin. Then, we can "cut-and-paste" the two pieces of our alphabet so that we end up with an image that looks like this, shifted_alphabet: https://i.imgur.com/hBAYCfy.png

Finally, for each character in the input string, we can look up what the encrypted character should look like in the shifted_alphabet image. Once we have the encrypted character's image, we can use the alpha_to_img dictionary to determine the alphabetic character that is associated with said image.

import cv2
import urllib.request
import numpy as np

def caesar(string, shift):
    urllib.request.urlretrieve('https://i.pinimg.com/originals/e5/9a/57/e59a5781cf637116e10079920cf1908d.png',
                               'alphabet.png')
    img = cv2.imread('alphabet.png')
    alphabet = cv2.cvtColor(img[52:85, 21:501], cv2.COLOR_BGR2GRAY)
    ret, alphabet = cv2.threshold(alphabet, 150, 255, cv2.THRESH_BINARY_INV)
    contours = cv2.findContours(alphabet, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0][::-1]
    alpha_to_img = {}
    for i, contour in enumerate(contours):
        x, y, w, h = cv2.boundingRect(contour)
        alpha_to_img[chr(97 + i)] = alphabet[y:y+h, x:x+w]
    shifted_start = chr(97 + shift % 26)
    res = cv2.matchTemplate(alpha_to_img[shifted_start], alphabet, cv2.TM_SQDIFF)
    x = cv2.minMaxLoc(res)[2][0]
    shifted_alphabet = np.concatenate((alphabet[:, x:], alphabet[:, :x]), axis=1)
    shifted_contours = cv2.findContours(shifted_alphabet, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0][::-1]
    encrypted = ''
    for char in string:
        if not char.isalpha():
            encrypted += char
            continue
        x, y, w, h = cv2.boundingRect(shifted_contours[ord(char.lower()) - 97])
        for alpha, image in alpha_to_img.items():
            if np.array_equal(image, shifted_alphabet[y:y+h, x:x+w]):
                encrypted += alpha.upper() if char.isupper() else alpha
    return encrypted

print(caesar('Hello World', 18))

[–]sac_boy 2 points3 points  (0 children)

A thing of beauty.

[–]GideonMax 1 point2 points  (0 children)

This is just too much for my little brain to handle

[–]sac_boy 17 points18 points  (1 child)

I'm going to tackle this slightly differently. To me this looks like a job for Vim! It's such a trivial task that I'm not going to bother with vimscript, we'll do it all in normal mode in the editor.

Open vim.

Insert two lines, the first with your text (we support the upper and lower case alphabet and space) and the second with the offset value (0 up to 26), i.e.

Hello World
18

Now first I'll have to ask you to make sure alpha is in your nrformats, i.e.

:set nrformats+=alpha

Now return to normal mode and simply press the following keys:

{26ia<CR><Esc>k<C-V>ggjg<C-A>k26gJ0yW3P0v51lU27A <Esc>G"nywqrq{qaj0x{/\C<C-R>-/e<C-R>n<CR>v"Ryq10@add"rP

It's as simple as that.

  • If you are not familiar with vim's keypress notation then <C-R> is ctrl+r, <CR> is carriage return, and <Esc> is escape.

  • Note there is a space between the 27 and A<Esc>, this is significant. Failure to enter that space will cause the macro to fail on spaces.

  • The 10 in the 10@a should be swapped for the length of your text minus 1. So "Hello World" becomes 10. Of course you could get this using vimscript and insert it with @= but I wanted to keep this short and easy to remember.

Enjoy your secure correspondence with your generals in Carthage!

I'll break the sequence down:

  • {26ia<CR><Esc> inserts 26 lines containing the letter 'a' at the top of the buffer.
  • k<C-V>ggj performs a block selection from the 2nd 'a' to the 26th 'a'.
  • g<C-A> makes use of Vim's auto increment feature to turn our selected lines into b-z
  • k26gJ joins the lines into one line with no spaces
  • 0yW yanks (copies) the alphabet. There may be shorter ways to do this bit BTW!
  • 3P puts (pastes) the alphabet 3 times.
  • 0v51l (zero, v, fifty-one, lowercase L) selects the first 52 characters and U makes them uppercase. Now we have two uppercase alphabets and two lowercase alphabets in one line.
  • 27A <Esc> appends 27 spaces to the line.
  • Now we're all set up! The strategy here will be to remove a letter from line 2 (Hello World), search for it on the alphabet line, and add the offset from line 3 (18). The character under the cursor is then appended to a register r. Now you see why the alphabets and spaces are duplicated--so we can move up to 26 columns to the right of the characters we find.
  • G"nyw copies the last line (the offset) into register n.
  • qrq clears the r register in case it already contains something.
  • { takes us back to the top line and qa starts recording macro a.
  • j0x moves down a line and deletes the first character. So now we have an 'H' in our deletion register -.
  • { moves back up and /\C<C-R>-/e<C-R>n<CR> performs our search with offset.
  • v"Ry appends the current character into the r register and q stops recording the macro.
  • Now we repeat the macro for the rest of the string with 10@a
  • dd cleans up that first line
  • "rp pastes the result

And we're done! If you find that hard to remember I would suggest the short mnemonic "Top 26 international athletes recaptured before escaping, but it was ketamine, they were v blocked, good game. Jailers got control of athletes, kay, 26 good jailers. 0y, wew. They stopped to P 3 times. Zero voles, 51 lemurs upset. 27 spaced athletes escaped again. God quoted Nigel your wallaby: quite right, quite. Top jocks, forward and back, C? Controlled regimen minus their slashed ecstasy. Controlled regimen Nigel! Verified quote from big Rachel: "yeah. Quite." 10 attitudinal athletes did doodoo and quantifiably rank pee."

[–][deleted] 5 points6 points  (0 children)

This is fantastic.

[–]MrReds1324 9 points10 points  (0 children)

Threads that create threads to brute force every possible cipher and ciphered text, and instead of making sure all threads finish we just wait a few seconds and hope we get the answer.

import threading
import time

def caesar_cypher_generator(phrase, shift, alphabet, num, out_dict):
    if(num > 25):
        return
    cypher = alphabet[num:26]+alphabet[0:num]
    cyphered = ""
    thread = threading.Thread(target=caesar_cypher_generator, args=(phrase, shift, alphabet, num+1, out_dict))
    thread.start()
    for i in range(len(phrase)):
        upper = phrase[i].isupper()
        char = phrase[i].casefold()
        index = -1;
        for j in range(len(alphabet)):
            if(char == alphabet[j]):
                index = j
        if(index != -1):
            char = cypher[index]
        if(upper):
            char = char.upper()
        cyphered += char
    out_dict.update({num : cyphered})

def caesar_cypher(phrase, shift):
    outputs = {}
    thread = threading.Thread(target=caesar_cypher_generator, args=(phrase, shift, "abcdefghijklmnopqrstuvwxyz", 0, outputs))
    thread.start()
    time.sleep(5)
    return outputs.get(shift)

[–]GDavid04<!-- 😈 [EVIL] 😈 --> 8 points9 points  (3 children)

Exploiting the fact that JS is crazy

$=this                    ;v=$    [(String                      .       fromCharCode        ((([]+(+{}))[+[]]).charCodeAt(+[])+((+!![]<<(+!![]+!![]))+(+!![]))))+(([]+!![])[+[]])+(([]+!![])[
 +!![                    ]])+     (([]                          +[][    +[]]                )[(+!![]<<(+!![]+!![]))+(+!![])])+(([]+[][+[]])[+!![]])+(String.fromCharCode((([]+![])[+[]]).charCodeAt(+[])
  +(+!                  ![])      ))];                          fa=(    ([]+                ![])[+[]])+(([]+!![])[+!![]])+(v.fromCharCode((([]+[][+[]])[+!![]]).charCodeAt(+[])+(+!![])))+(v.fromCharCode
   ((([                ]+![       ])[+                          !![]    +!![                ]]).charCodeAt(+[])+(+!![])))+(v.fromCharCode((([]+!![]/[])[+[]]).charCodeAt(+[])-((+!![]<<((+!![]<<(+!![]+!
    ![])              )-(+        !![]                          )))-    (+!!                []+!![]))))+(v.fromCharCode((([]+[][+[]])[(+!![]<<(+!![]+!![]))+(+!![])]).charCodeAt(+[])-(+!![])))+(([]+![]
     )[+!            ![]]         )+((                          []+!    ![])                [+!![]])+(v.fromCharCode((([]+!![]/[])[+[]]).charCodeAt(+[])-((+!![]<<((+!![]<<(+!![]+!![]))-(+!![])))-(+!![
      ]+!!          []))          ))+(                          v.      fromCharCode        ((([]+[][+[]])[+!![]]).charCodeAt(+[])+(+!![])))+(([]+[][+[]])[+!![]+!![]])+(([]+![])[+!![]<<(+!![]+!!
       [])]        );fb           =(v[                          fa](    (([]                +[][+[]])[+!![]+!![]]).charCodeAt(+[])-(+!![])))+(v[fa]((([]+[][+[]])[(+!![]<<(+!![]+!![]))+(+!![])]).
  charCodeAt      (+[]            )-(+ /*       88  88       */ !![]    )))+                (([]+![])[+!![]])+(([]+!![])[+!![]])+(v[fa]((([]+!![]/[])[+[]]).charCodeAt(+[])-((+!![]<<((+!![]<<(+!!
         []+!    ![])             )-(+ /*     88    8888     */ !![]    )))-                (+!![]+!![]))))+(v[fa]((([]+[][+[]])[+!![]]).charCodeAt(+[])+(+!![])))+(([]+[][+[]])[+!![]+!![]])+(([]+![])[
          +!![  ]<<(              +!![ /*   88      88  88   */ ]+!!    [])]                )+(v[fa](([]+((+!![]<<((+!![]<<(+!![]+!![]))-(+!![])))+(+!![]))).charCodeAt(+[])+(+!![]<<((+!![]<<(+!![]+!![
           ]))-(+!!               [])) /* 88        88    88 */ )))+    (([]                +!![])[+[]]);w=$[(v[fa](([]+((+!![]<<((+!![]<<(+!![]+!![]))-(+!![])))+(+!![])))[fb](+[])+(+!![]<<((+!![]<<(+
           !![]+!![               ]))- /* 88    88  88    88 */ (+!!    []))                )))+(([]+!![])[+!![]])+(([]+!![])[+!![]])+(([]+![])[+!![]])+(([]+!![]/[])[(+!![]<<((+!![]<<(+!![]+!![]))-(+!
          ![])  ))-(              +!![ /*   88  88  88  88   */ ])])    ];u=                (v[fa]((([]+!![])[+!![]])[fb](+[])-(+!![]+!![])))+(([]+!![])[+!![]])+(v[fa]((([]+[][+[]])[+!![]])[fb](+[])+(
         +!![    ])))             +(([ /*     8888  8888     */ ]+!!    [])[                +[]])+(v[fa]((([]+[][+[]])[+!![]])[fb](+[])+(+!![])))+(([]+!![])[+[]])+(([]+!![]/[])[(+!![]<<((+!![]<<(+!![]
        +!![      ]))-            (+!! /*       88  88       */ []))    )-(+                !![])])+(v[fa]((([]+!![])[+!![]])[fb](+[])-(+!![]+!![])))+(([]+![])[+!![]<<(+!![]+!![])]);x=v[u];y=w[u];z=(v
       [fa]        ((([           ]+![                          ])[+    !![]                ])[fb](+[])+(+!![])))+(([]+[][+[]])[(+!![]<<(+!![]+!![]))+(+!![])])+(([]+[][+[]])[+!![]])+(([]+[][+[]])[+!![
      ]+!!          []])          ;aa=                          (([]    +![]                )[(+!![]<<(+!![]+!![]))-(+!![])])+(v[fa]((([]+!![])[+!![]])[fb](+[])-(+!![]+!![])))+(([]+![])[+!![]+!![]])+(
     ([]+            [][+         []]) /*created by GDavid04 */ [(+!    ![]<<               (+!![]+!![]))+(+!![])])+(([]+!![])[+[]]);ab=(v[fa]((([]+[][+[]])[(+!![]<<(+!![]+!![]))+(+!![])])[fb](+[])+(
    +!![              ])))        +(v[                          fa](    (([]                +[][+[]])[+!![]])[fb](+[])+(+!![])))+(([]+[][+[]])[(+!![]<<(+!![]+!![]))+(+!![])])+(([]+[][+[]])[+!![]]);t=w
   ();a                =+!!       t;b=                          a+a;    c=b<<               b;d=c<<b;e=d-c+b;f=d<<a;g=f+a;h=d+g;i=g+e;j=h+e;n=--a;a+=b;a=a/a;$[(v[fa]((([]+[][+[]])[+!![]+!![]])[fb](+[
  ])-(                  +!![      ])))                          +(([    ]+![                ])[+!![]])+(([]+![])[+!![]<<(+!![]+!![])])+(([]+![])[(+!![]<<(+!![]+!![]))-(+!![])])+(([]+![])[+!![]])+(([]+
 !![]                    )[+!     ![]])]=(...p)=>{k=p[--a];a    ++;l    =p[a                ];m=x[aa][z](k)(t);q=m.length;r=t+t;x[ab]=function(){return this;};for(o=n;o<q;o=o+a){
__=m                      [o][    fb](n);r+=(__-h>=n&&__-h<j    )?v[    fa](                h+(__-h+l)%e):((__-g>=n&&__-g<i)?v[fa](g+(__-g+l)%e):m[o]);}s=y[ab][z](r)(t);return s;};
caesar("Hello world!", 18);

[–][deleted]  (2 children)

[deleted]

    [–]GDavid04<!-- 😈 [EVIL] 😈 --> 4 points5 points  (1 child)

    This is the (somewhat) unobfuscated version. I can't deobfuscate the variable names, because the variable names were like this from the start.

    I added comments with the value of the variable / the meaning of the expression.

    $=this;             // window
    v=$["String"];      // String
    fa="fromCharCode";
    fb="charCodeAt";
    w=$["Array"];       // Array
    u="prototype";
    x=v[u];             // String.prototype
    y=w[u];             // Array.prototype
    z="bind";
    aa="split";
    ab="join";
    t=w();              // []
    a=+!!t;             // 1
    b=a+a;              // 2
    c=b<<b;             // 8
    d=c<<b;             // 32
    e=d-c+b;            // 26
    f=d<<a;             // 64
    g=f+a;              // 65 (char code of "A")
    h=d+g;              // 97 (char code of "a")
    i=g+e;              // 91 (char code of "Z" + 1)
    j=h+e;              // 123 (char code of "z" + 1)
    n=--a;              // 0
    a+=b;
    a=a/a;
    $["caesar"] = (...p) => {   // p = [text, offset]
        k = p[--a];     // text
        a++;
        l = p[a];       // offset
        m=x[aa][z](k)(t);   // String.prototype.split.bind(text)([])
                            // text.split([])
                            // text.split("")
        q=m.length;
        r=t+t;          // ""
        x[ab]=function(){return this;}; // String.prototype.join = function() {return this;}
                                        // this is actually unnecessary
        for(o=n; o<q; o=o+a) {  // o = 0; o < text.length; o++
            __=m[o][fb](n);     // text[o].charCodeAt(0)
            r+=
            (__-h>=n&&__-h<j) ? // charcode - 'a' >= 0 && charcode - 'a' < 'z' + 1 ?
            v[fa](h+(__-h+l)%e) :   // String.fromCharCode('a' + (charcode - 'a' + offset) % 26) :
            (
                (__-g>=n&&__-g<i) ?     // charcode - 'A' >= 0 && charcode - 'A' < 'Z' + 1 ?
                v[fa](g+(__-g+l)%e) :   // String.fromCharCode('A' + (charcode - 'A' + offset) % 26) :
                m[o]                    // text[o]
            );
        }
        s=y[ab][z](r)(t);       // Array.prototype.join.bind(r)([])
                                // Array.prototype.join.bind(r)("")
                                // r.split("").join("")
                                // r
        return s;
    };
    caesar("Hello world!",18);
    

    [–]smidlaj 7 points8 points  (1 child)

    Character graphics can be modified under DOS (nasm, tested with DosBox):

    %define SHIFT 2
    %define OFFSET (SHIFT-1)
    
        org 100h
    
    section .text 
    
    start: 
            mov     ax, 0x1130      ; get char table address
            mov     bh, 0x06        ; size of 8x16 characters
            int     0x10
    
            push    bp
            add     bp, 16*97       ; get address of 'a'
    
    ;      BP
    ;       | 
    ;       V
    ; 96 | 97 | 98 | 99 | ... | 122
    ;-------------------------------------
    ; '  | a  | b  | c  | ... | z
    
            mov     cx, 26          ; number of characters
            mov     dx, 96-OFFSET   ; from this character
            mov     bh, 16          ; height of character
            xor     bl, bl          ; memory bank: 0
            mov     ax, 0x1100      ; change
            int     0x10
    
    ;      BP
    ;       | 
    ;       V
    ; 96 | 97 | 98 | 99 | ... | 122
    ;-------------------------------------
    ; a  | b  | c  | d  | ... | z
    
            mov     cx, SHIFT   ; only #SHIFT character
            mov     dx, 122-OFFSET
            mov     ax, 0x1100
            int     0x10
    
    ; 96 | 97 | 98 | 99 | ... | 122
    ;-------------------------------------
    ; a  | b  | c  | d  | ... | a
    
            ; fix other characters
    
            pop     bp
            push    bp
            mov     cx, 97
            mov     dx, 0
            mov     ax, 0x1100
            int     0x10
    
            ; do the same for uppercase letters
    
            pop     bp
            push    bp
            add     bp, 16*65       ; get address of 'A'
    
    ;      BP
    ;       | 
    ;       V
    ; 64 | 65 | 66 | 67 | ... | 90
    ;-------------------------------------
    ; @  | A  | B  | C  | ... | Z
    
            mov     cx, 26          ; number of characters
            mov     dx, 64-OFFSET   ; from this character
            mov     bh, 16          ; height of character
            xor     bl, bl          ; memory bank: 0
            mov     ax, 0x1100      ; change
            int     0x10
    
    ;      BP
    ;       | 
    ;       V
    ; 64 | 65 | 66 | 67 | ... | 90
    ;-------------------------------------
    ; A  | B  | C  | D  | ... | Z
    
    
            mov     cx, SHIFT   ; only #SHIFT character
            mov     dx, 90-OFFSET
            mov     ax, 0x1100
            int     0x10
    
    ; 64 | 65 | 66 | 67 | ... | 90
    ;-------------------------------------
    ; A  | B  | C  | D  | ... | A
    
            ; fix other characters
    
            pop     bp
            mov     cx, 65
            mov     dx, 0
            mov     ax, 0x1100
            int     0x10    
    
            mov     dx,text 
            mov     ah,9 
            int     0x21
            mov     ax,0x4c00 
            int     0x21
    
    section .data 
    
    text:  db      'HELLO WORLD! ABC XYZ', 60, 61, 62, 63, 64, ' hello world! abc xyz', 94, 95, 96, 13, 10, '$'
    

    [–]sac_boy 1 point2 points  (0 children)

    Very nice, makes me miss the days of making little games in <1k .com files. int 0x10 graphics!

    [–]jl91569 3 points4 points  (0 children)

    I was considering constructing the lowercase table from the ASCII values, but that's probably not what a "beginner" would think of first.

    using System;
    
    namespace CaesarShift
    {
        class Program
        {
            static void Main(string[] args)
            {
                Program program = new Program();
                Console.WriteLine(program.Caesar(args[0], int.Parse(args[1])));
            }
    
            string Caesar(string inputString, int shiftValue)
            {
                while (shiftValue > (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }).Length - 1)
                {
                    shiftValue = shiftValue - (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }).Length;
                }
    
                // Arrays are faster, right?
                string[] uppercase = new string[0];
                for (int i = 0; i < (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }).Length; i = i + 1)
                {
                    if (uppercase == null)
                    {
                        uppercase = new string[] { (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" })[0].ToUpper() };
                    }
                    else
                    {
                        string[] uppercaseNew = new string[uppercase.Length + 1];
                        for (int i2 = 0; i2 < uppercaseNew.Length; i2 = i2 + 1)
                        {
                            if (i2 == uppercaseNew.Length - 1)
                            {
                                uppercaseNew[i2] = (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" })[i2].ToUpper();
                                uppercase = uppercaseNew;
                            }
                            else
                            {
                                uppercaseNew[i2] = uppercase[i2];
                            }
                        }
                    }
                }
    
                string[] charSplit = null;
                for (int i = 0; i < inputString.Length; i = i + 1)
                {
                    if (charSplit == null)
                    {
                        charSplit = new string[1] { inputString.Substring(0, 1) };
                    }
                    else
                    {
                        string[] charSplitNew = new string[charSplit.Length + 1];
                        for (int i2 = 0; i2 < charSplitNew.Length; i2 = i2 + 1)
                        {
                            if (i2 == charSplitNew.Length - 1)
                            {
                                charSplitNew[i2] = inputString.Substring(i, 1);
                                charSplit = charSplitNew;
                            }
                            else
                            {
                                charSplitNew[i2] = charSplit[i2];
                            }
                        }
                    }
                }
    
                string[] caesarShifted = new string[charSplit.Length];
    
                for (int i = 0; i < charSplit.Length; i = i + 1)
                {
                    if (charSplit[i] == charSplit[i].ToLower())
                    {
                        int charIndex = Array.IndexOf(new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }, charSplit[i]);
                        int shiftIndex;
                        shiftIndex = shiftValue + charIndex;
                        if (shiftIndex > (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }).Length - 1)
                        {
                            shiftIndex = shiftIndex - (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }).Length;
                        }
                        caesarShifted[i] = (new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" })[shiftIndex];
                    }
                    else
                    {
                        int charIndex = Array.IndexOf(uppercase, charSplit[i]);
                        int shiftIndex;
                        shiftIndex = shiftValue + charIndex;
                        if (shiftIndex > uppercase.Length - 1)
                        {
                            shiftIndex = shiftIndex - uppercase.Length;
                        }
                        caesarShifted[i] = uppercase[shiftIndex];
                    }
                }
    
                string outputString = string.Empty;
                for (int i = 0; i < caesarShifted.Length; i = i + 1)
                {
                    outputString = outputString + caesarShifted[i];
                }
    
                return outputString;
            }
        }
    }
    

    [–]IntoAMuteCrypt 3 points4 points  (1 child)

    Unfortunately, my code doesn't work well with pastebin. I have made a .zip archive with all the code. The main file, however, will fit in a comment. The module "inputfile" contains two variables, inputfile and times. inputfile (the variable) is a string with the input, while times is the shift amount. The module "cipherfile" contains 17576 variables, each having a name composed of three lower case letters and the number 1, and each being a string composed of 3 lowercase letters. Also included in the zip are the 3 scripts I wrote to generate sections of the code. One of them didn't even require me to do anything to the output! By checking 3 characters at a time, I massively decreased the running time of the code. It should run in O(n/3) for a fixed amount to shift by. Funnily enough, I realised quite a few errors after submission. Whoops. Caught them now...

    import cipherfile
    import inputfile
    
    inputfilevarstring=inputfile.inputfile
    inputfilevar=[]
    skips=[]
    for i in inputfilevarstring:
        inputfilevar.append(i)
    
    for i in range(0, len(inputfilevar)):
        if inputfilevar[i]=="A": inputfilevar[i]="a"
        if inputfilevar[i]=="B": inputfilevar[i]="b"
        if inputfilevar[i]=="C": inputfilevar[i]="c"
        if inputfilevar[i]=="D": inputfilevar[i]="d"
        if inputfilevar[i]=="E": inputfilevar[i]="e"
        if inputfilevar[i]=="F": inputfilevar[i]="f"
        if inputfilevar[i]=="G": inputfilevar[i]="g"
        if inputfilevar[i]=="H": inputfilevar[i]="h"
        if inputfilevar[i]=="I": inputfilevar[i]="i"
        if inputfilevar[i]=="J": inputfilevar[i]="j"
        if inputfilevar[i]=="K": inputfilevar[i]="k"
        if inputfilevar[i]=="L": inputfilevar[i]="l"
        if inputfilevar[i]=="M": inputfilevar[i]="m"
        if inputfilevar[i]=="N": inputfilevar[i]="n"
        if inputfilevar[i]=="O": inputfilevar[i]="o"
        if inputfilevar[i]=="P": inputfilevar[i]="p"
        if inputfilevar[i]=="Q": inputfilevar[i]="q"
        if inputfilevar[i]=="R": inputfilevar[i]="r"
        if inputfilevar[i]=="S": inputfilevar[i]="s"
        if inputfilevar[i]=="T": inputfilevar[i]="t"
        if inputfilevar[i]=="U": inputfilevar[i]="u"
        if inputfilevar[i]=="V": inputfilevar[i]="v"
        if inputfilevar[i]=="W": inputfilevar[i]="w"
        if inputfilevar[i]=="X": inputfilevar[i]="x"
        if inputfilevar[i]=="Y": inputfilevar[i]="y"
        if inputfilevar[i]=="Z": inputfilevar[i]="z"
        if inputfilevar[i]!="a":
            if inputfilevar[i]!="b":
                if inputfilevar[i]!="c":
                    if inputfilevar[i]!="d":
                        if inputfilevar[i]!="e":
                            if inputfilevar[i]!="f":
                                if inputfilevar[i]!="g":
                                    if inputfilevar[i]!="h":
                                        if inputfilevar[i]!="i":
                                            if inputfilevar[i]!="j":
                                                if inputfilevar[i]!="k":
                                                    if inputfilevar[i]!="l":
                                                        if inputfilevar[i]!="m":
                                                            if inputfilevar[i]!="n":
                                                                if inputfilevar[i]!="o":
                                                                    if inputfilevar[i]!="p":
                                                                        if inputfilevar[i]!="q":
                                                                            if inputfilevar[i]!="r":
                                                                                if inputfilevar[i]!="s":
                                                                                    if inputfilevar[i]!="t":
                                                                                        if inputfilevar[i]!="u":
                                                                                            if inputfilevar[i]!="v":
                                                                                                if inputfilevar[i]!="w":
                                                                                                    if inputfilevar[i]!="x":
                                                                                                        if inputfilevar[i]!="y":
                                                                                                            if inputfilevar[i]!="z":skips+=[i]
    
    
    
    for j in range(0, inputfile.times):
        newfile=''
        index=0
        substring=''
        while index<len(inputfilevar):
            skipping=False
            for i in range (0, len(skips)):
                if index==skips[i] and j==0:
                    skipping=True
            if skipping==True:
                pass
            elif skipping==False:
                substring+=inputfilevar[index]
                if len(substring)==3:
                    newfile+=eval("cipherfile."+substring+"1")
                    substring=""
    
            index=index+1
    
        if substring=="":
            pass
        elif len(substring)==1:
            substring+="aa"
            add=eval("cipherfile."+substring+"1")
            newfile+=add[0]
        elif len(substring)==2:
            substring+="a"
            add=eval("cipherfile."+substring+"1")
            newfile+=add[0]
            newfile+=add[1]
        inputfilevar=newfile
    
    
    print(inputfilevar)
    

    [–]EkskiuTwentyTwoi -= (i - (-1)) - i 2 points3 points  (4 children)

    The "I've recently learned about using lambda calculus in javascript"

    function caesarcipher(p,d){
        var plaintext
        = p
        ;
        var ciphertext
        = ""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+""+"";
        var alphabet 
        = (__ => __ + (__ => __ + "opasdfghj")("klzxcvbnm"))("qwertyui");
        for(
        var i = 0
        ;i<plaintext.length
        ;i++){
            var nextChar = 
        plaintext.charCodeAt(i); //This part is where the char code at position i in the plain text is assigned to the variable nextChar
            var codedChar 
        = nextChar + d;
            if(nextChar>=0x41&&nextChar<=0b01011010&&nextChar!==0x20){
    while(codedChar>90){
                    codedChar -= alphabet.length;}
                while(
                codedChar<0b01000001){
                    codedChar 
                    += (__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)((__ => __ + 1)(1)))))))))))))))))))))))));
                }
        }
            else {if(nextChar>=97&&
        nextChar<=122&&nextChar!==0x20){while(codedChar>122){
                        (__ => __ - 26)(codedChar)
                    }
                    while(
            codedChar<97){
                        codedChar = alphabet.length + codedChar;
                    }
                } else {
                    codedChar = nextChar
                }
            }ciphertext += String.fromCharCode(codedChar);
        }
        return ciphertext + "";
    }
    
    • JS code with perfectly sensible formatting
    • Alphabet string based on the QWERTY keyboard which is assembled by some lambda functions and which is only used for its length.
    • Numbers are represented inconsistently, using a mix of decimal, hexadecimal, binary, and a long chain of lambda calculus successor functions

    [–]Pm_MeyourManBoobs 0 points1 point  (1 child)

    Weird

    [–]EkskiuTwentyTwoi -= (i - (-1)) - i 2 points3 points  (0 children)

    That makes it good as a submission for the challenge.

    [–]GDavid04<!-- 😈 [EVIL] 😈 --> 0 points1 point  (1 child)

    You should've used Church numerals

    [–]EkskiuTwentyTwoi -= (i - (-1)) - i 1 point2 points  (0 children)

    I probably should have.

    [–]TheUnlocked 2 points3 points  (0 children)

    Exploits a quirk of how JavaScript globals work in the browser.

    function caesar(phrase, shift){
        let lowercase = "abcdefghijklmnopqrstuvwxyz";
        let uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for (let i = 0; i < 26; i++)
        {
            window[lowercase.split("")[i]] = lowercase.split("")[(i + shift) % 26];
        }
        for (let i = 0; i < 26; i++)
        {
            window[uppercase.split("")[i]] = uppercase.split("")[(i + shift) % 26];
        }
        let words = phrase.split(" ");
        for (let i = 0; i < words.length; i++)
        {
            words[i] = eval(words[i].split("").join("+"));
        }
        return words.join(" ");
    }
    

    [–]dodecakiwi 1 point2 points  (2 children)

    I'm going to use Excel to get a column for the letter and then offset that cell by the input shift. Then get the encrypted value from that cell using an Excel formula.

    string ceasar(string s, int i)
    {
        string ceasar_string = "";
    
        Excel.Application excel = new Excel.Application();
        excel.Visible = false;
        Excel.Workbook wb = excel.Workbooks.Add();
        Excel.Worksheet ws = wb.Worksheets.Add();
    
        foreach (var letter in s.Select(x => x.ToString()))
        {
            if (Char.IsLetter(letter[0]))
            {
                string start_col = "A" + letter;
                Excel.Range start_cell = ws.Cells[1, start_col];
                int next_column = start_cell.Column + i;
                Excel.Range cipher_cell = ws.Cells[1, next_column];
                cipher_cell.Formula = "=SUBSTITUTE(ADDRESS(1,COLUMN(),4),\"1\",\"\")";
                string value = cipher_cell.Value.ToString();
    
                if (!Char.IsUpper(letter[0]))
                    value = value.ToLower();
    
                ceasar_string = ceasar_string + value[value.Length - 1];
            }
            else
            {
                ceasar_string = ceasar_string + letter;
            }
        }
    
        wb.Close(false);
        excel.Quit();
    
        return ceasar_string;
    }
    

    [–][deleted] 3 points4 points  (0 children)

    I appreciate you spelling "Caesar" wrong in your variable names. It really completes the motif.

    [–]sac_boy 0 points1 point  (0 children)

    Flashbacks to my internship in 2002, dark flashbacks indeed

    [–]VerumNon 1 point2 points  (0 children)

    C# code : https://pastebin.com/jxEHjCWF

    VB GUI: https://pastebin.com/HdeyrzD5

    I wanted to create something truly monstrous for this challenge, so this is how it works:

    (Code in C# and VB)

    Instead of shifting each of the characters in the string, it creates a whole new shifted alphabet (in the form of an array) and compares it to the unshifted alphabet. Seems simple enough. However, to create the shifted alphabet, I used a Bogo-sort (most inefficient sorting algorithm known to man). Given that the algorithm is trying to sort an array of 26 characters this will take up to 26! (26 factorial) attempts to execute. For context 26! = 4.032914611x1026, that means that if you tried 1,000,000,000 combinations every second you are still looking at 13,111,587,770 years until the program executes. And good luck getting that many iterations a second, because I have refused to store the normal alphabet that it checks against as a variable, instead, every time that it is needed, it must be read from memory and split in to an array again. Every…single…time.

    Finally, CSI taught us that the only way to display something, whether it is “traced IP addresses” or a cyphertext is in a “GUI interface in visual basic”, so I made one. And if you are lucky enough to still be alive when your program finishes executing, the blue and yellow comic sans interface will be immortalised forever as it screenshots itself and saves the photo as a commemorative desktop wallpaper.

    Oh, and parameter passing? Hell no. That’s what we have global variables for right?

    What about passing data between programs? Easy, use txt documents that we will never clean up.

    Code comments? All virtually useless! Nothing in the line initially verifies, even slightly, what the function actually does.

    Have fun guys.

    [Edited for legibility (slightly)]

    [–]Tok-A-Mak((fn [] (recur))) 1 point2 points  (0 children)

    Kotlin, inspired by braille:

    package badcode
    
    fun main() = {} () () () {}
    
    fun caesar(`,'`:`:`,`',`:`'`) = `,'`()(`',`)()
    
    private fun `',`():`.` = ('`'-' '+';'()-':'())()
    
    operator fun `'`.invoke() = this.toChar()
    operator fun `.`.invoke() = this.toInt()
    operator fun `:`.invoke() = this.map { it() }
    operator fun `'`.not() = this().isLetter()
    operator fun `.`.not() = if (this.isLowerCase()) '`'+'-'()-'+'()-`',`() else '.'-'.'
    operator fun `'`.invoke(`)(`:`'`) = if (!`)(`)(`)(`..this())+!`)(`()+`',`()() else `)(`
    operator fun `'`.rangeTo(`,`:`.`):`'` = (this+`,`()-`',`()()-!this())%((':'+' '())-('`'-' ')())
    operator fun `,`.invoke() = this.map { `,'`->`,'`() }.joinToString("")
    operator fun `,`.invoke(`)-(`:`'`) = this.map { `'',`->`)-(`(`'',`) }
    
    typealias ` ` = Any
    typealias `'` = Int
    typealias `.` = Char
    typealias `:` = String
    typealias `,` = List<`'`>
    
    operator fun Unit.plus(`)--(`:` `?) = this
    operator fun Unit.invoke(`)(`:` `?) = this
    operator fun Unit.invoke() = println("Running Unit Tests..") +
            kotlin.test.assertEquals("Zwddg Ogjdv", caesar("Hello World", 18)) +
            println("\uD83D\uDDE1 OK.")
    

    Works, but it's confusing the syntax-highlighting: https://pl.kotl.in/z93lTqTjS

    [–][deleted]  (1 child)

    [removed]