469,270 Members | 1,733 Online

# Cipher/decipher program 2
I'm trying to make a simple program that will convert to and from a cipher that's already set.

Expand|Select|Wrap|Line Numbers
1. foo = 'a = hz\nb = ye\nc = uo\nd = pd\ne = qi\nf = jy\ng = ru\nh = sw\ni = ln\nj = ae\nk = na\nl = rt\nm = wu\nn = is\no = nd\np = hw\nq = op\nr = kb\ns = vf\nt = fc\nu = xr\nv = ex\nw = mn\nx = gb\ny = bu\nz = ie\n. =  *right wing slash* \n, =  *hand wave* \n" =  *hand curve* \n! =  *double hand jerk* \n? =  *wing wave* \n... =  *squiggly hand motion* '
2. repl={}
3. reverse_repl={}
4. import sys
5. #Generate replacement tables
6. for str in foo.split("\n"):
7.     parts=str.split(" = ")
8.     repl[parts]=parts
9.     repl[parts.lower()]=parts
10.     reverse_repl[parts]=parts
11. def encipher():
12.     outstr = ''
14.     i = 0
15.     for i in range(len(instr)):
16.         c = instr[i]
17.         if (instr[i:i+3]=='...'):
18.             outstr+=repl['...']
19.             i+=3
20.         else:
21.             if (c in repl):
22.                 outstr+=repl[c]
23.                 i+=1
24.             else:
25.                 outstr+=c
26.                 i+=1
27.     print outstr
28. def decipher():
29.     outstr = ''
31.     instr=instr[:-1]
32.     i = 0
33.     c = instr[i]
34.     while (i<len(instr)):
35.             if (instr[i:i+2]):
36.                 outstr+=reverse_repl[instr[i:i+2]]
37.                 i+=2
38.             else:
39.                 outstr+=c
40.                 i+=1
41.     print outstr
42. if (sys.argv=="-e"):
43.     encipher()
44. else:
45.     decipher()
46. raw_input('press Return to end program>')
Couple of things I couldn't get working:
1. I couldn't separate the '...' from the '.' The '...' will give the correct equivalent from the list when enciphering, but will also follow it with 2 instances of '.'
2. For deciphering, it works up until it goes up against a character that's not in "foo" like 123 or a space.

Dec 14 '08 #1
4 6446 bvdet
2,851 Expert Mod 2GB
It appears that you want to replace each character with a unique 2 character string with a special exception for "...". I don't understand what *squiggly hand motion* is, but I'll assume that it is 2 characters. If a character is not in repl, double it so we be consistent.

Expand|Select|Wrap|Line Numbers
1.     for i in range(len(instr)):
2.         c = instr[i]
3.         if (instr[i:i+3]=='...'):
4.             outstr+=repl['...']
5.             i+=3
6.         else:
7.             if (c in repl):
8.                 outstr+=repl[c]
9.                 i+=1
10.             else:
11.                 outstr+=c
12.                 i+=1
Variable i is updated each iteration. If you assign i in the body of the loop, you will lose the assignment.
Expand|Select|Wrap|Line Numbers
1.     while i < len(instr):
2.         c = instr[i]
3.         if instr[i:i+3] == '...':
4.             outstr += repl['...']
5.             i+=3
6.         elif c in repl:
7.             outstr += repl[c]
8.             i+=1
9.         else:
10.             outstr += c*2
11.             i+=1

To get the code to work, I replaced your code:
Expand|Select|Wrap|Line Numbers
1.     while (i<len(instr)):
2.             if (instr[i:i+2]):
3.                 outstr+=reverse_repl[instr[i:i+2]]
4.                 i+=2
5.             else:
6.                 outstr+=c
7.                 i+=1
with the following code:
Expand|Select|Wrap|Line Numbers
1.     while i<len(instr):
2.         if reverse_repl.has_key(instr[i:i+2]):
3.             outstr += reverse_repl[instr[i:i+2]]
4.         else:
5.             outstr += instr[i]
6.         i+=2
There were several places in your code where parentheses were not required. Avoid using str as a variable name, because the built-in function str() will be masked.
HTH --BV
Dec 14 '08 #2
slurpz
2 Thanks for the quick reply. I actually worked a bit on my code while I waited so my code looks pretty similar to yours. My code looks like this right now:

Expand|Select|Wrap|Line Numbers
1. foo = 'a = hz\nb = ye\n... =  *squiggly hand motion* \nc = uo\nd = pd\ne = qi\nf = jy\ng = ru\nh = sw\nI = xegy\ni = ln\nj = ae\nk = na\nl = rt\nm = wu\nn = is\no = nd\np = hw\nq = op\nr = kb\ns = vf\nt = fc\nu = xr\nv = ex\nw = mn\nx = gb\ny = bu\nz = ie\n. =  *right wing slash* \n, =  *hand wave* \n" =  *hand curve* \n! =  *double hand jerk* \n? =  *wing wave* '
2. repl={}
3. reverse_repl={}
4. import sys
5. #Generate replacement tables
6. for str in foo.split("\n"):
7.     parts=str.split(" = ")
8.     repl[parts]=parts
9.     repl[parts.lower()]=parts
10.     reverse_repl[parts]=parts
11. def encipher():
12.     outstr = ''
14.     i = 0
15.     n = len(instr)
16.     while i < n:
17.         c = instr[i]
18.         if instr[i:i+3] == '...':
19.             outstr += repl['...']
20.             i+=3
21.         elif c in repl:
22.             outstr += repl[c]
23.             i+=1
24.         else:
25.             outstr += c
26.             i+=1
27.     print outstr
28. def decipher():
29.     outstr = ''
31.     i = 0
32.     n = len(instr)
33.     while i < n:
34.         if instr[i:i+2] in reverse_repl:
35.             outstr+=reverse_repl[instr[i:i+2]]
36.             i+=2
37.         else:
38.             outstr+=instr[i]
39.             i+=1
40.     print outstr
41. if (sys.argv=="-e"):
42.     encipher()
43. else:
44.     decipher()
45. raw_input('press Return to end program>')
Enciphering works perfectly (that "..." fix was great), but now with deciphering, there are a couple values that take up more than 2 letters.

These include:
*right wing slash* = .
*hand wave* = ,
*hand curve* = "
*double hand jerk* = !
*wing wave* = ?
*squiggly hand motion* = ...
xegy = I

Is there a more efficient way than searching for each one individually? (Maybe from an array or something?)
Dec 14 '08 #3
bvdet
2,851 Expert Mod 2GB
You should consider processing these special cases separately. Example:
Expand|Select|Wrap|Line Numbers
1. dd = {'*right wing slash*': '.',
2.       '*hand wave*': ',',
3.       '*hand curve*': '"',
4.       '*double hand jerk*': '!',
5.       '*wing wave*': '?',
6.       '*squiggly hand motion*': '...',
7.       'xegy': 'I'}
8.
9. def fix_str(s):
10.     for key in dd:
11.         s = s.replace(key, dd[key])
12.     return s
Expand|Select|Wrap|Line Numbers
1. >>> print fix_str("*right wing slash**hand wave**hand curve*")
2. .,"
3. >>>
Dec 14 '08 #4
MojaveKid
9 2 digit encryption...the closest thing to this will be the BIFID cipher

 6 posts views Thread by Michael Sparks | last post: by 4 posts views Thread by Carl Harris | last post: by 7 posts views Thread by Piotr Turkowski | last post: by 9 posts views Thread by Piotr Turkowski | last post: by 1 post views Thread by mkazek | last post: by 2 posts views Thread by Julio C. Hernandez Castro | last post: by 1 post views Thread by beetle17 | last post: by 16 posts views Thread by Cawas | last post: by 4 posts views Thread by wagn31 | last post: by reply views Thread by ioana budai | last post: by 1 post views Thread by CARIGAR | last post: by reply views Thread by SioSio | last post: by 2 posts views Thread by SwissProgrammer | last post: by reply views Thread by shivambhatele | last post: by 1 post views Thread by cyogarajmsc | last post: by reply views Thread by sanil123 | last post: by 1 post views Thread by junedadenwalla | last post: by 2 posts views Thread by MinkeAccess | last post: by