Reputation: 39
I'm fairly new to programming so forgive me if there's an obvious answer here.
I essentially want to apply a permutation to a string. If the string isn't the same length as the permutation, I want to add a 'Z' to make the length a multiple of the permutation's length. The problem is if say the permutation is length 4 and the string is length 8, how do I get it to apply the permutation to the second half of the string?
here's what I have so far
def encr(k, m):
if len(m)%len(k)!=0:
for i in range((int(len(m)%len(k)))):
m+=str('Z')
return apply(m, k)
and heres the apply function called on in the previous function
def apply(L,P):
A = list(range(len(L)))
for i in range(len(L)): A[i] = L[P[i]]
return A
I want to apply the permutation to a string in order to do a simple for of encryption. It would just switch the index of the letters in the string. But if the string is longer than the permutation how do I get the permutation to apply more than once to the same string. For example: Permutation = [2,3,0,1,4] and the string would be "hello" it would make it "llheo" but if the string is "hello_world", how do I get the permutation to start over again after the 4th index? I apologize if I'm confusing, I just don't know how to word it.
Upvotes: 0
Views: 187
Reputation: 1007
Okay I hope I'm understanding you correctly. What I think you're asking is if you give a list of characters and a list of indexes to rearrange those characters how can you:
A. add characters to the end of the characters list to make the length a multiple of the length of the index list
and
B. make the index list repeat on character lists that are longer than the index lists (i.e [4,0,1,3,2] would be used twice on a 10 character long list)
if that is indeed the case then here is my response....
Firstly if you just added random characters to the word to be a multiple of the perm then repeated the perm you would have an issue with your word would ALWAYS be scrambled in groups of the length of your perm. I.E. if your perm was 5 characters long and your text was 'aaaaabbbbbcccccddddd' the result would always be 'aaaaabbbbbcccccddddd' no matter what the order of the permutation was. But since i don't know exactly what you're using it for, here is what you've asked for I think....
this will add a 'Z' to the end of a list of characters until the length is a multiple of the length of the permutation order. I think thats what you were wanting. Also i've commented out a line that will instead add a random lowercase character instead of adding 'Z' in case you found that helpful.
import random
def enc(oldword, perm):
while len(oldword)%len(perm)!=0:
oldword.append('Z')
## oldword.append(chr(random.randrange(97,123)))
newword=[]
while len(oldword)>0:
for i in perm:
newword.append(oldword[i])
for _ in range(len(perm)):
oldword.pop(0)
return newword
Now taking a guess from the name of your function 'enc' if you are trying to scramble a word or sentence using a key (like your permutation list) that you can also use to DECRYPT the message I would suggest making a slight modification. Instead of supplying a perm list you could have the input be a NUMBER and then use that number like so:
count the characters in the string repeatedly until you reach that number then remove that character from the string and repeat the process from that point. for example if the word was 'hello' and the number was 7 you would count the 5 characters in the word hello then go back to the h for number 6 and the e would be 7. you would remove the 'e' making the remaining string 'hllo' and your new string would be 'e' so far. Then count to 7 again starting with the place you left off. repeat that until there are no more characters in your string.
A more detailed example....
For the text 'hello_world' using a number of 65
def enc(oldword, siferkey):
#be sure that the oldword is a list of characters i.e. ['a','b','c']
oldword=[oldword[i] for i in range(len(oldword))]
newword=[]
dex=0
while len(oldword)>0:
dex+=siferkey-1
while dex not in range(len(oldword)):
dex-=len(oldword)
newword.append(oldword.pop(dex))
return newword
print enc(['h','e','l','l','o','_','w','o','r','l','d'],65)
would return ['r', 'l', 'w', 'e', '_', 'l', 'l', 'o', 'o', 'h', 'd'] Then to unscramble it you would use this:
def dec(wrd, sifer):
dex=0
newword=['' for _ in range(len(wrd))]
dex+=sifer-1
while dex not in range(len(newword)):
dex-=len(newword)
newword[dex]=wrd.pop(0)
counter=0
while len(wrd)>0:
counter+=sifer
while counter>0:
dex+=1
if dex not in range(len(newword)):
dex=0
if newword[dex]=='':
counter-=1
newword[dex]=wrd.pop(0)
return newword
Please forgive me if i'm completely wrong on the direction you were trying to go here.
Upvotes: 1