wahlysadventures
wahlysadventures

Reputation: 139

Reading and writing to files in python, translating text in one file to another

I open 2 files and read them. I have a helper function that creates a random 31 character string of the alphabet + ",';.?"

For example the function may create the line "seokgxavu?'bq,cr.ihwt;yjzmdfpnl" which contains all 31 characters and are in a random order, the helper function creates 2 of these lines and writes them to secret.txt.

So say the two random secret lines are:

seokgxavu?'bq,cr.ihwt;yjzmdfpnl    
dcurmk'ltbgjyfan?;ohzieps,vxwq.

For every letter inside english.txt, each should have its own corresponding secret.txt letter. And every time it does a letter, it will get the next from the other secret line. For example "Hello" would output "vmbja"

v because "h" is where it would be in the first secret line.
m because "e" is where it would be in the second secret line.
b because "l" is where it would be in the FIRST secret line (notice how it went back to the first, this should continue.)

with open("english.txt", 'r') as e:
    PlainText = e.read()
with open("secret.txt", 'r') as s:
    SharedKeys = s.read()    


with open("code.txt", 'w') as c:

    x = english[0]               
    y = secret[0]
    x = y



    code.write(str(x))    

The code above will match up the first letter in the english.txt with the first letter in the secret.txt and then will write that to code.txt. BUT, I am unsure on how to repeat this so that it will do it for an entire paragraph of text. Any tips or pointers are appreciated! Thanks.

Upvotes: 0

Views: 680

Answers (2)

OneCricketeer
OneCricketeer

Reputation: 191701

I got "vmbjc" for "hello" ... I think that is what you meant because when you alternate the secret line, you look for the "o" position in the first secret line, which has a "c". The second secret has as "a" at that position.

english = "abcdefghijklmnopqrstuvwxyz" + ",';.?"
secret = []
with open("secrets.txt" , "r") as s:
    secret = [line.rstrip() for line in s]

cypher = dict((c, [x[i] for x in secret]) for i, c in enumerate(english))

def translate(s):
    secret_index = 0
    trans = []
    for c in s:
        # not sure how spaces are dealt with
        trans.append(cypher[c][secret_index] if not c == ' ' else ' ')
        secret_index = (secret_index + 1) % len(secret)
    return ''.join(trans)

print(translate("hello")) # vmbjc

UPDATE: Expanded cypher assignment

cypher = {}
for i in range(len(english)): # for each english character
    c = english[i]
    secrets = []
    for j in range(len(secret)): # for each corresponding secret character
        secrets.append(secret[j][i])
        cypher[c] = secrets # make a mapping of english character to list-of-secret-characters
    secrets = [] # clear out list of secret characters for the next english character

Upvotes: 2

M.T
M.T

Reputation: 5231

What about using a dictionary to translate from code? You could do something like:

e='abcdefghi' #etc.
s='seokgxavu'
s_to_e={}#depending on which you need
e_to_s={}
for i in range(len(e)):#assuming s and e have same length 
    s_to_e[s[i]]=e[i]
    e_to_s[e[i]]=s[i]
code_str='seo'
decoded=''
plain_str='hifi'
encoded=''
for i in range(len(code_str)):
    decoded+=s_to_e[code_str[i]]
for i in range(len(plain_str)):
    encoded+=e_to_s[plain_str[i]]
#encoded should now be 'vuxu' and decoded 'abc'

You would have to map whitespace(newline, space, etc.) as well to do a paragraph or more, doing something like:

s_to_e[' ']=' '. or adding it straight to both english and secret as s='cdfa ', e='abcd '

Upvotes: 0

Related Questions