when i say basic i mean basic it doesnt store the encrypted string in a file or anything it just prints out what it would be and all i intend it to do is swap a for b, b for c and so on then turn the string round backwards once its done that. and the decrypt would be turinng it round backwards again then changing b to a, c to b etc. anyway i have forgotten how to turn the string round backwards allthough i am pretty sure it has something to do with slicing like
a = pie
b = a[3:0]
print a
print b
with my expetced output being
pie
eip
and with the actual output being
pie
[this is a blank line]
anyway if someone can help with that or if you have a better method that would be great, anyway here is the code.

#simple encryption program
import os
list = ['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','a']
choice = 0
while choice != 2:
os.system("cls")
    print "Encryption/Decryption Program"
    print "-" * 10
    print "0 - Encrypt Text"
    print "1 - Decrypt Text"
    print "2 - Quit"
    choice = input("Choose: ")
    if choice == 0:
        print "Enter the string to be encrypted below"
        text = raw_input()
        for letter in range(1,27):
            letter2 = letter + 1
            text.replace(list[letter], letter2)
        print "Your text encrypted is",text                  
    elif choice == 1:
        print "Enter the string to be decyrpted below"
        text = raw_input()
        for letter in range(27,1):
            letter2 = letter - 1
            text.replace(list[letter], letter2)
        print "Your text decrypted is ",text
    elif choice == 2:
        print "Bye"
    else:
        print "Please enter either 0,1 or 2"
    raw_input()   
#End

The problem is on this line

text.replace(list[letter], letter2)

and the error i get is

Traceback (most recent call last):
File "C:\Python25\Decrypt_Encrypt.py", line 20, in <module>
text.replace(list[letter], letter2)
TypeError: expected a character buffer object

i might just be using the wrong command or syntax or this might just not work at all and iam being a idiot but either way ied like help with this. thanks.

Recommended Answers

All 19 Replies

Sounds like you want to do a simple swap crypting, something like this?

# simple crypt using a swap of 2 adjoining characters

def swap_crypt(str1):
    """
    this function will encrypt/decrypt a string
    """
    # change string to a mutable list of characters
    list1 = list(str1)
    # iterate the list with step=2
    for k in range(0, len(list1), 2):
        if len(list1) > k + 1:
            # do a swap of groups of 2 items each in the list
            list1[k], list1[k+1] = list1[k+1], list1[k]
    # change list back to a string
    return ''.join(list1)

str1 = 'love to eat pie'
# encrypt the string
str2 = swap_crypt(str1)

print str1  # love to eat pie
print str2  # olevt  oae tipe

# decrypt the encrypted string
str3 = swap_crypt(str2)

print str3  # love to eat pie

thanks i guess allthough a explanation as to where my code is going wrong would be good. i should probably have said i probably know nothing about python compared to the average person on these boards. I would like to learn more but my attitude stops me iam to lazy and i lack determination and get frustrated with things quite easy. I like programming i just dont like learning how to program.

when i say basic i mean basic it doesnt store the encrypted string in a file or anything it just prints out what it would be and all i intend it to do is swap a for b, b for c and so on then turn the string round backwards once its done that. and the decrypt would be turinng it round backwards again then changing b to a, c to b etc. anyway i have forgotten how to turn the string round backwards allthough i am pretty sure it has something to do with slicing like
a = pie
b = a[3:0]
print a
print b
with my expetced output being
pie
eip
and with the actual output being
pie
[this is a blank line]
anyway if someone can help with that or if you have a better method that would be great, anyway here is the code.

#simple encryption program
import os
list = ['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','a']
choice = 0
while choice != 2:
os.system("cls")
    print "Encryption/Decryption Program"
    print "-" * 10
    print "0 - Encrypt Text"
    print "1 - Decrypt Text"
    print "2 - Quit"
    choice = input("Choose: ")
    if choice == 0:
        print "Enter the string to be encrypted below"
        text = raw_input()
        for letter in range(1,27):
            letter2 = letter + 1
            text.replace(list[letter], letter2)
        print "Your text encrypted is",text                  
    elif choice == 1:
        print "Enter the string to be decyrpted below"
        text = raw_input()
        for letter in range(27,1):
            letter2 = letter - 1
            text.replace(list[letter], letter2)
        print "Your text decrypted is ",text
    elif choice == 2:
        print "Bye"
    else:
        print "Please enter either 0,1 or 2"
    raw_input()   
#End

The problem is on this line

text.replace(list[letter], letter2)

and the error i get is

Traceback (most recent call last):
File "C:\Python25\Decrypt_Encrypt.py", line 20, in <module>
text.replace(list[letter], letter2)
TypeError: expected a character buffer object

i might just be using the wrong command or syntax or this might just not work at all and iam being a idiot but either way ied like help with this. thanks.

Well, several things here (if you don't mind the long explanation):

(1) This caused several problems:

for letter in range(1,27):
             letter2 = letter + 1
             text.replace(list[letter], letter2)

The error you saw happened because you were trying to replace the string 'list[letter]' with an integer 'letter2', which can't work; you have to replace strings with strings. Hence: text.replace(list[letter],list[letter2]) gets rid of that error.

But then, your code ran off the end of list because the highest value for letter2 is going to be 27, but the highest index in list is 26 (check me on those statements). So instead of range(1,27), we want 'range(26)'.

Then after all that, the string still doesn't change. That's because the line 'text.replace(...)' returns the new string, but you don't store the result anywhere. We want 'text = text.replace(...)'

Here's the new section of code:

if choice == 0:
        print "Enter the string to be encrypted below"
        text = raw_input()
        for letter in range(26): # <---
            letter2 = letter + 1
            text = text.replace(list[letter], list[letter2])
        print "Your text encrypted is",text                  
    elif choice == 1:
        print "Enter the string to be decyrpted below"
        text = raw_input()
        for letter in range(26): # <---
            letter2 = letter - 1
            text = text.replace(list[letter], list[letter2])
        print "Your text decrypted is ",text

Having fixed all that, something bad now happens:

Encryption/Decryption Program
----------
0 - Encrypt Text
1 - Decrypt Text
2 - Quit
Choose: 0
Enter the string to be encrypted below
blah
Your text encrypted is aaaa

ACK!

So we walk through the code manually:

for letter in range(26):
    print list[letter], list[letter+1]
    text = text.replace(list[letter], list[letter+1])
    print text

    
a b
blbh
b c
clch
c d
dldh
d e
eleh
e f
flfh
f g
glgh
g h
hlhh
h i
ilii
i j
jljj
j k
klkk
k l
llll
l m
mmmm
m n
nnnn
n o
oooo
o p
pppp
p q
qqqq
q r
rrrr
r s
ssss
s t
tttt
t u
uuuu
u v
vvvv
v w
wwww
w x
xxxx
x y
yyyy
y z
zzzz
z a
aaaa

Oohh... the code replaces each a with b and then each b with c, which causes both 'natural' b's and a's changed into b's to become c's. Eventually, everything becomes an a.

One solution is to walk through the list backwards:

for letter in range(25,-1,-1): # goes from 25 to 0 counting by -1
   letter2 = letter + 1
   text = text.replace(list[letter], list[letter2])

Which gives the results

Encryption/Decryption Program
----------
0 - Encrypt Text
1 - Decrypt Text
2 - Quit
Choose: 0
Enter the string to be encrypted below
blah
Your text encrypted is cmbi

Encryption/Decryption Program
----------
0 - Encrypt Text
1 - Decrypt Text
2 - Quit
Choose: 1
Enter the string to be decyrpted below
cmbi
Your text decrypted is  blah

If you want to reverse a string, the following is good:

rev = s[::-1]

That expression takes a slice from end to beginning, taking characters -1 at a time.

Hope it helps,
Jeff

But then, your code ran off the end of list because the highest value for letter2 is going to be 27, but the highest index in list is 26 (check me on those statements). So instead of range(1,27), we want 'range(26)'.

now thats what a call a explanation :cheesy:. as for the quote above there i think your wrong about that because well heres a example.

for i in range(1,10):
    print i

the output you would expect is just 1 to 10 but its actully 1 to 9. anyway thanks for explaning why my code is completely useless and flawed and in such great detail (this may sound sarcastic but i assure you its not). some of the mistakes i would have figured out myself like not actully assigning it to anything. ill look over the redone code and see how it works.

sorry for double posting i cant find the edit button but i have found 1 problem with the program you have given me. when i try to encrpyt 'z' it will come out as b becuase it changes z to a then a to b. it works the same when decrypting the 'b' it comes out as z becuase it changes b to a then a to z.

sorry for double posting i cant find the edit button but i have found 1 problem with the program you have given me. when i try to encrpyt 'z' it will come out as b becuase it changes z to a then a to b. it works the same when decrypting the 'b' it comes out as z becuase it changes b to a then a to z.

Oohh. Good testing. Sorry to let that slip through.

Briefly back to this:

But then, your code ran off the end of list because the highest value for letter2 is going to be 27, but the highest index in list is 26 (check me on those statements). So instead of range(1,27), we want 'range(26)'.

for i in range(1,10):
    print i

The output you would expect is just 1 to 10 but its actully 1 to 9.

You're right about your example. The tricky part is that letter2 = letter + 1, so that the highest value of *letter* is 26, so that the highest value of letter2 will be 27.

OK: how to fix the cypher 'z' bug?

I think the real problem is that you process the text 26 times, and the letters get touched 26 times each. So whether you go up or down, something's guaranteed to get mis-encrypted. Further, your algorithm only really works if *all* of the characters go up or down, which doesn't really help when you want to do a random substitution like the Cryptograms in the newspapers.

So: what if you re-wrote your algorithm so that each letter only gets touched once? I'll bet you could do that with a for loop, and maybe the functions ord() and chr().

Jeff

So: what if you re-wrote your algorithm so that each letter only gets touched once? I'll bet you could do that with a for loop, and maybe the functions ord() and chr().

i do see the problem with my method in that theres allways going to be something misencrypted but i dont really know what u mean by touching each letter only once and using chr and ord. chr and ord turn things into and outof ascii yes?. are you suggesting go through the list letter by letter and changing it to ascii then adding 1? then changing it back to a number using ord? what would happen then at z then when it would change it to [ maybe a if statement to see if it ascii code was that then insted of adding one chaning it to 97 for a?. ill see what i can do :confused:.

If you just want to do rotational crypting, Python has that builtin ...

# example of simple encoding using rot13 encoding
# alphabet is shifted by 13 positions to nopqrstuvwxyzabcdefghijklm
# so original 'a' becomes 'n' and so on

text = "i am crazy"

print "original =", text  # i am crazy

encoded = text.encode('rot13')

print "encoded  =", encoded  # v nz penml

decoded = encoded.encode('rot13')

print "decoded  =", decoded  # i am crazy

are you suggesting go through the list letter by letter and changing it to ascii then adding 1? then changing it back to a number using ord? what would happen then at z then when it would change it to [ maybe a if statement to see if it ascii code was that then insted of adding one chaning it to 97 for a?. ill see what i can do :confused:.

Precisely. It's much cleaner and faster than the text.replace() calls.

Jeff

This is what i have come up with for the encryption i plan to add things to it but that will be after it works :rolleyes:.

def encrypt(text_f):
    length = len(text_f)
    for position in range (1,length):
        temp = ord(text_f[position - 1: position])
        temp = temp + 1
        temp = chr(temp)
        print temp
        text_f[position - 1: position] = temp

print 'blah'
print encrypt('blah')

i added in the print temp to see if it was working to change the b into a c up until i get the error. I t does print out the blah and the c after that so it works up until this error.

Traceback (most recent call last):
File "C:/Python25/Decrypt_Encrypt2.py", line 15, in <module>
print encrypt('blah')
File "C:/Python25/Decrypt_Encrypt2.py", line 12, in encrypt
text_f[position - 1: position] = temp
TypeError: 'str' object doesn't support slice assignment

with the main line being 'str' object doesn't support slice assignment.
i tried to see if it was talking about temp so i forced it to be a integer replacing temp with int(temp) but that gave me this error.

text_f[position - 1: position] = int(temp)
ValueError: invalid literal for int() with base 10: 'c'

the rest of the error is the same as the one above. any help would be great.

edit: and i just realised that position position - 1 thing is overcomplciated becuase i can just do text_f[position] etc i thought you could only do that with lists :/

the edit button seems to disapper a while after you reply but anyway i also realised the 0,length is overcomplicated as it starts at 0 anyway so it should just be length

got it working heres the code.

def encrypt(text_f):
    length = len(text_f)
    for position in range (length):
        temp = ord(text_f[position])
        temp = temp + 1
        temp = chr(temp)
        text_f = text_f[:position] + temp + text_f[position + 1:]
    return text_f

and the decrypt is the same except with - 1. now to make it more complicated :cheesy:

Good job!

I like especially that you turned it into a function. You could now extend that a bit to accomplish encrypting and decrypting at once: have 'encrypt' accept an argument 'displace' (or some better name) that indicates how many letters up or down to translate the character. Thus, encryption would be

encrypt(text, 1)

and decryption would be

encrypt(text,-1)

Also: your z's aren't going to work yet.

Jeff

Member Avatar for Mouche

I tried it out myself and came up with the following code. It adds to a new string created in the functions to create the encoded or decoded text.

def encode(text):
    encoded = ""
    for letter in text:
        if letter in "abcdefghijklmnopqrstuvwxy":
            encoded += chr(ord(letter)+1)
        elif letter == "z":
            encoded += "a"
        else:
            encoded += letter
    return encoded

def decode(text):
    decoded = ""
    for letter in text:
        if letter in "bcdefghijklmnopqrstuvwxyz":
            decoded += chr(ord(letter)-1)
        elif letter == "a":
            decoded += "z"
        else:
            decoded += letter
    return decoded

s = raw_input("Enter a string to encode: ")
s_encoded = encode(s)
print '"%s" encrypts to:\n%s' % (s, s_encoded)
s_decoded = decode(s_encoded)
print '"%s" decrypts to:\n%s' % (s_encoded, s_decoded)

Here was my successful output:

>>> 
Enter a string to encode: I love daniweb.com! wootz!
"I love daniweb.com! wootz!" encrypts to:
I mpwf ebojxfc.dpn! xppua!
"I mpwf ebojxfc.dpn! xppua!" decrypts to:
I love daniweb.com! wootz!

I know you seem to have mostly figured this out, but I thought I'd just give it a try.


Note: My algorithm would need to be changed in order to adapt the functions to accept varying numbers of rotation for the encryption.

def en_de_code(text,flag=0):
        if flag == 0:
                return ''.join([chr(ord(char) + 1) for char in text ]) #encode
        else:
                return ''.join([chr(ord(char) - 1) for char in text ]) #decode

ive made a good vb text editor with encryption program using XOR (you enter a passphrase to open the document)

if you want the code you can have it. might be able to translate it into c or something

Ghostdog:
thats a pretty clever bit of code ill use it when i fully understand it (or else it just feels like cheating)

jrcagle:
i realised that my z's dont need to come out as a its encryption its meant to look weird.
also iam trying to work it so that it can encrypt/decrypt on the same function. allthough its slightly harder now that i made it more complicated.

lamouche:
nice to see other people doing the same thing :cheesy: and from what i understand of your code it seems good.

jbennet:
thanks for the offer but iam useless with vb and c the only things i do know are Truebasic (have to use that in school not by choice) and python and i dont even know much about either of those :P.

Member Avatar for Mouche

Wow, ghostdog. That's short code. Talk about clean. I can understand that... the list comprehensiong stuff, but I have yet to implement it into something of my own. I don't think about using it when I'm designing something...it's just not in my brain yet.


jrcagle:
i realised that my z's dont need to come out as a its encryption its meant to look weird.
also iam trying to work it so that it can encrypt/decrypt on the same function. allthough its slightly harder now that i made it more complicated.

Actually, you'll have a hard time decrypting if your z's don't have a unique target value. Of course, that value could be any character -- such as '!'. Perhaps that's what you have in mind.

Jeff

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.