Python 使用排列作为键对消息字符串进行解扰
帮助我正在尝试使用排列作为密钥对文件进行解扰,我知道如何对其进行加扰,但我需要创建一个函数,将其解扰回使用相同排列密钥时的状态,以下是代码:Python 使用排列作为键对消息字符串进行解扰,python,string,permutation,Python,String,Permutation,帮助我正在尝试使用排列作为密钥对文件进行解扰,我知道如何对其进行加扰,但我需要创建一个函数,将其解扰回使用相同排列密钥时的状态,以下是代码: def stringtoarray(S): A = [] i = 0 while i<len(S): A.append(S[i]) i += 1 return A def arraytostring(A): S = "" for c in A: # "for each
def stringtoarray(S):
A = []
i = 0
while i<len(S):
A.append(S[i])
i += 1
return A
def arraytostring(A):
S = ""
for c in A: # "for each element/value c in array A"
S = S+c
return S
#arraytostring
def scramble(S, P): #Scramble string S with permutation P
pn = len(P) # length of permutation array
E = (len(S) + pn - (len(S)%pn)) * [' '] # array of chars, padded
i = 0
while i< len(S):
seg = i/pn # segment number
j = i % pn # segment offset
E[ seg*pn + P[j] ] = S[i]
i += 1
# while
return arraytostring(E)
# scramble
print scramble("0123456789abcdefghij",[9, 14, 11, 19, 16, 18, 12, 6,
7, 15, 0, 5, 17, 4, 3, 10, 2, 1, 8, 13])
# prints ahgedb78i0f26j194c53
def stringtoarray:
A=[]
i=0
而我首先对你的代码做了一些评论
以下内容完全没有必要:
def stringtoarray(S):
A = []
i = 0
while i<len(S):
A.append(S[i])
i += 1
return A
您的arraytostring
函数也是不必要的。将列表连接成字符串的正确方法是使用。例如,'.join(['a','b','c'])
将为您提供'abc'
这是我将如何执行加扰/解扰功能:
def scramble(s, p):
chars = list(s)
scrambled = ['']*len(chars)
for char, i in zip(chars, p):
scrambled[i] = char
return ''.join(scrambled)
def unscramble(s, p):
reverse_p = sorted(range(len(p)), key=p.__getitem__)
return scramble(s, reverse_p)
s = "abcdefg"
p_key = [6, 1, 3, 0, 5, 2, 4]
print "original:", s
scrambled = scramble(s, p_key)
print "scrambled:", scrambled
print "unscrambled:", unscramble(scrambled, p_key)
结果:
original: 0123456789abcdefghij
scrambled: ahgedb78i0f26j194c53
unscrambled: 0123456789abcdefghij
原件:0123456789abcdefghij
加扰:ahgedb78i0f26j194c53
解读:0123456789abcdefghij
简单。计算置换的倒数并应用它。这有一个众所周知的算法;你可以在Donald Knuth的《计算机编程的艺术》中找到被称为算法J的算法
这里似乎有源代码:
void inversePermutation(int perm[],int n,int inv[]){
对于(int i=0;i从某种意义上说,您已经编写了解扰器。您所要做的就是将扰码器
输入到下面。逆排列由argsort(p)
给出,其中p
是排列
顺便说一下,与其预先为E
分配足够的空间,还不如
E = (len(S) + pn - (len(S)%pn)) * [' ']
您可以使用argsort
按顺序生成E
中的项目:
def scramble(S, P):
pn = len(P)
E = []
idx = argsort(P)
for i in range(len(S)):
seg,j = divmod(i,pn)
E.append(S[idx[j]+seg*pn])
return ''.join(E)
你不应该用这个来保护任何东西。我相信这是一个有趣的编程挑战或其他东西,在这种情况下,对你来说更强大。你确定扰码器是正确的吗?计算E的长度应该做什么?提示:检查len(E)
看看它是否正确。你认为seg
是什么?(提示:对于你的例子,它总是零)是的,这是我需要做的,但我有一个困难的时间输入到我的代码
def scramble(S, P): #Scramble string S with permutation P
pn = len(P) # length of permutation array
E = (len(S) + pn - (len(S)%pn)) * [' '] # array of chars, padded
for i in range(len(S)):
seg,j = divmod(i,pn)
E[ seg*pn + P[j] ] = S[i]
return ''.join(E).rstrip()
def argsort(seq):
# http://stackoverflow.com/questions/3382352/3382369#3382369
'''
>>> seq=[1,3,0,4,2]
>>> index=argsort(seq)
[2, 0, 4, 1, 3]
Given seq and the index, you can construct the sorted seq:
>>> sorted_seq=[seq[x] for x in index]
>>> assert sorted_seq == sorted(seq)
Given the sorted seq and the index, you can reconstruct seq:
>>> assert [sorted_seq[x] for x in argsort(index)] == seq
'''
return sorted(range(len(seq)), key=seq.__getitem__)
P=[9, 14, 11, 19, 16, 18, 12, 6, 7, 15, 0, 5, 17, 4, 3, 10, 2, 1, 8, 13]
text="0123456789abcdefghij"
print scramble(text,P)
# ahgedb78i0f26j194c53
print(scramble(scramble(text,P),argsort(P)))
# 0123456789abcdefghij
E = (len(S) + pn - (len(S)%pn)) * [' ']
def scramble(S, P):
pn = len(P)
E = []
idx = argsort(P)
for i in range(len(S)):
seg,j = divmod(i,pn)
E.append(S[idx[j]+seg*pn])
return ''.join(E)