Modern Code Ring

From Robo-T
Jump to: navigation, search

Code Rings were used for centuries. A simple example would be to shift the letters so many degrees.

 A  B  C  D  E  F  G  H  I ...
 M  N  O  P  Q  R  S  T  U ...

Where A is represented by M and B by N. Another implementation could be a mixture of letters.

 A  B  C  D  E  F  G  H  I ...
 R  W  B  S  P  I  J  D  Q ...

In honor of code ring encryption, I have created a program that uses this basis for encryption. Some methods used to increase the difficult of the encryption include:

  • letters of higher frequency are randomly represented by different letters.
  • spaces are have 6 different random characters to represent it. This accounts for frequency.
  • Random seed is dispersed at random intervals in a frequency that is proportional to letter frequency

These methods help counteract the most obvious ways of cracking code ring encryption. Being the creator of the code it seems very difficult to evaluate the security of the encryption. Even so it seems pretty sound. Any thoughts would be appreciated.

Sample key created

kr1 is the name of the key The second value the letter y is represented by 1.

 kr1,y,1,c,l,a,Qv,i,YB,p,p, ,aquZKJ,z,y,w,f,f,6,v,g,.,3I,s,WH,j,x,e,VmS,n,Us,
   comma,GP,h,TN,b,X,l,5t,m,d,o,ce,g,i,u,O,x,w,r,kL,q,9,d,Cr,seed,2zjEFn7AbDoR,t,8M4,k,h,

Message encrypted

This message was encrypted using the above key, kr1.

This is a test. We will see two variants.

to the following two variants, however in practice you would never allow the passing of both variations.

8TYHaBWZvEu4SH8IzJnfmRKfnBzt5qWSmja8fcbJgvFL7YQU8HI
4TBHJEY2WuvuMSW283afVEK2f7BEtta7HSSq8FfeugQLoBQU4H3

both will decrypt to the original message but in all lower cases.

Code

## Uses Python 3 
## Modern-Code-Ring-1 encryption#####
##Version: 0.5
##Author:TOPSECRET
##Location:TOPSECRET
##This program will create an encryption/decryption scheme based on
##  a Code Ring encryption where a letter is represented by another letter.
##  However the encryption is reinforced by 2 other factors
##    -Multiple letters to represent one letter to account for frequency analysis.
##    -Seed radomly despersed at the rate of 1:5 with account to frequency
##
##  presently messages are turned to lower case for simplicity
##  extention for key files is .mcr1
##

import random

def make_key(chrset='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789',output=False):
    frequency={'e':3,'t':3,'a':2,'o':2,'i':2, 'n':2,'s':2,'h':2,'r':2,'d':2,'l':2}
    alpha=list(chrset)
    alpha2=alpha.copy()
    random.shuffle(alpha2)
    made_key=dict()
    place=0
    for i in range(26):
        number=1
        if alpha[i] in frequency:
            number=frequency[alpha[i]]
        letters=[]
        for x in range(number):
            letters.append(alpha2[place])
            place+=1
            new=''.join(str(n) for n in letters)
        made_key[alpha[i]]=new
        if output:print (alpha[i],new)
    letters=[]
    for i in range(6):
        letters.append(alpha2[place])
        place+=1
        new=''.join(str(n) for n in letters)
    made_key[' ']=new
    if output:print(' ',new)
    letters=[]
    for i in range(2):
        letters.append(alpha2[place])
        place+=1
        new=''.join(str(n) for n in letters)
    made_key[',']=new
    if output:print(',',new)
    letters=[]
    for i in range(2):
        letters.append(alpha2[place])
        place+=1
        new=''.join(str(n) for n in letters)
    made_key['.']=new
    if output:print('.',new)
    letters=[]
    for i in range(12):
        letters.append(alpha2[place])
        place+=1
        new=''.join(str(n) for n in letters)
    made_key['seed']=new
    if output:print('seed',new)
    return made_key

def print_key(key):
    keys=[]
    for i in key:
        keys.append(i)
    keys.remove('seed')
    keys.sort()
    print('\n'+'seed'+' - '+key['seed'])
    for i in keys:
          print(i+' - '+key[i])        

def my_encode(message='',key={}):
    encoded=''
    message=message.lower()
    for i in message:
        if random.choice([0,0,0,0,1]):
            encoded=encoded+random.choice(key['seed'])
        encoded=encoded+random.choice(key[i])
    return encoded        

def my_decode(code='',key={}):
    decoded=''
    for i in code:
        for d in key:
            if i in key[d]:
                new=d
        if new=='seed':
            new=''
        decoded=decoded+new
    return decoded

def save_encoding(file,key_name,key={}):
    ring=''
    for item in key:
        if item==',': ring=ring+'comma'+','+key[item]+','
        else: ring=ring+item+','+key[item]+','
    name=key_name+','
    fout=open(file,'a')
    fout.write(name+ring+'\n')
    fout.close()

def load_encoding(file,name):
    fin=open(file,'r')
    code_key=None
    make_key=dict()
    for line in fin:
        code_ring=line.strip().split(',')
        if code_ring[0]==name:
            code_key=True
            for i in range(1,len(code_ring)-1,2):
                if code_ring[i]=='comma':make_key[',']=code_ring[i+1]
                else: make_key[code_ring[i]]=code_ring[i+1]
    if not code_key:
        print("key with such name not found.")
    return make_key

def intro():
    print('TOPSECRET: MCR1-"Modern-Code-Ring-1" encryption program.')
    print('IMPORTANT: If used properly the code should be uncrackable.')
    print('  *Though the algorythm should hold for some reuse, each key should only be used once.')
    print('  *Long messages, repetative messages or messages with generally know structure or content may weaken the cipher.')
    print('  *The keys and files containing the keys must be kept safe always.')
    print('   Both sides must be in possision of this program and the apporiate files with keys.')
    print('   It is possible to decode by hand with the keys.')
    print('     However encoding by hand will introduce great weakness that can compromise the code.')
    print('   To decode one need the file, the name of the key and the message.')
    print('   For the sake of simplicity all letters are turned to lower-case.')
    print('   The only other characters allowed are spaces, commas, and periods.')
    print()

def menu():
    print("What do you want to do?")
    print("   1 - Change file of keys. Now using ('"+file+"')")
    print('   2 - Make new keys.')
    print('   3 - Encode.')
    print('   4 - Decode.')
    print('   5 - Quit.')
    return input('Choice: ')

def file_choice():
    file=input("What file of keys do you want to use? ")
    file=file+'.mcr'
    return file

def menu_make_keys():
    num=int(input("How many keys do you want to create? "))
    prefix=input("What prefix would you like to use? ")
    fout=open(file,'a')
    for i in range(1,num+1):
        new=make_key()
        save_encoding(file,prefix+str(i),new)
    fout.close()
    print("Done. Entered encodings "+prefix+'1-'+prefix+str(num)+'\n')

def menu_encode():
    print("The file, "+file+" contains the following encodings: ")
    fin=open(file)
    key_ring=[]
    for ring in fin:
        code_ring=ring.strip().split(',')
        key_ring.append(code_ring[0])
    fin.close()
    print(key_ring)
    notpresent=True
    while notpresent:
        ring=input("Which key do you want to use?  ")
        if ring in key_ring: break
        print("No such key.")
    message=input("What message do you want to encrypt? ")
    key=load_encoding(file,ring)
    code=my_encode(message,key)
    print("The encoded message is: ")
    print(" "*5+code+'\n')

def menu_decode():
    print("The file, "+file+" contains the following encodings: ")
    fin=open(file)
    key_ring=[]
    for ring in fin:
        code_ring=ring.strip().split(',')
        key_ring.append(code_ring[0])
    fin.close()
    print(key_ring)
    notpresent=True
    while notpresent:
        ring=input("Which key do you want to use? ")
        if ring in key_ring: break
        print("No such key.")
    message=input("What message do you want to decrypt? ")
    key=load_encoding(file,ring)
    code=my_decode(message,key)
    print("The encoded message is: ")
    print(" "*5+code+'\n')

####begining of program proper#####

intro()
file=file_choice()
while True:
    choice=menu()
    if   choice == '1': file=file_choice()    
    elif choice == '2': menu_make_keys()    
    elif choice == '3': menu_encode()
    elif choice == '4': menu_decode()
    elif choice == '5': break