python - 出于某种原因,只要在 if 语句中检查条件,就会重置列表 chars 的值,从而破坏程序
问题描述
我正在尝试制作一个接收字符串并运行以下加密算法的函数:字母表中奇数位置 i 处的每个字符都将使用位置 i + 1 处的字符进行加密,并且偶数位置处的每个字符我将用位置 i - 1 处的字符加密。换句话说,“a”用“b”加密,“b”用“a”加密,“c”用“d”加密,“d”用“c”加密,以及很快。小写字符应保持小写,大写字符应保持大写。换句话说,“bob”将输出为“apa”。
尽管我最终发现了这个问题,但我仍然不知道为什么在我的条件句中使用 chars[i] 而不是 stg[i] 会破坏程序。从我的观察来看,该列表似乎是随机重置的。谁能解释为什么交换变量修复了我的程序?谢谢!
损坏的程序:
def easyCryto(stg=''):
# Alphabet list
alpha = ['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']
cap_alpha = [i.upper() for i in alpha]
# Converts the string into a list
chars = []
for char in stg:
chars.append(char)
# Encyription Algorithm
for i in range(len(chars)):
for j in range(len(alpha)):
# Checks if letter are odd
if (j + 1) % 2 == 1:
if chars[i] == alpha[j]:
try: # Block 1
if chars[i] not in cap_alpha:
chars[i] = alpha[j + 1]
else:
chars[i] = cap_alpha[j + 1]
except:
if chars[i] not in cap_alpha:
chars[i] = alpha[0]
else:
chars[i] = cap_alpha[0]
elif chars[i] == cap_alpha[j]:
chars[i] = cap_alpha[j + 1]
# Checks if letter are even
elif (j + 1) % 2 == 0:
if chars[i] == alpha[j]:
try: # Block 1
if chars[i] not in cap_alpha:
chars[i] = alpha[j - 1]
else:
chars[i] = cap_alpha[j - 1]
except:
if chars[i] not in cap_alpha:
chars[i] = alpha[-1]
else:
chars[i] = cap_alpha[-1]
elif chars[i] == cap_alpha[j]:
chars[i] = cap_alpha[j - 1]
return ''.join(chars)
print(easyCryto('Willy'))
固定程序:
def easyCryto(stg=''):
# Alphabet list
alpha = ['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']
cap_alpha = [i.upper() for i in alpha]
# Converts the string into a list
chars = []
for char in stg:
chars.append(char)
# Encyription Algorithm
for i in range(len(chars)):
for j in range(len(alpha)):
# Checks if letter are odd
if (j + 1) % 2 == 1:
if stg[i] == alpha[j]:
try: # Block 1
if stg[i] not in cap_alpha:
chars[i] = alpha[j + 1]
else:
chars[i] = cap_alpha[j + 1]
except:
if stg[i] not in cap_alpha:
chars[i] = alpha[0]
else:
chars[i] = cap_alpha[0]
elif stg[i] == cap_alpha[j]:
chars[i] = cap_alpha[j + 1]
# Checks if letter are even
elif (j + 1) % 2 == 0:
if stg[i] == alpha[j]:
try: # Block 1
if stg[i] not in cap_alpha:
chars[i] = alpha[j - 1]
else:
chars[i] = cap_alpha[j - 1]
except:
if stg[i] not in cap_alpha:
chars[i] = alpha[-1]
else:
chars[i] = cap_alpha[-1]
elif stg[i] == cap_alpha[j]:
chars[i] = cap_alpha[j - 1]
return ''.join(chars)
print(easyCryto('bob'))
解决方案
问题是您在更换后永远不会跳出循环,因此更换循环会继续进行。这在替换“向后”时不是问题,例如用 a 替换 b,因为您正在alpha
向前迭代,所以它不会再次匹配。但是,当您替换a
为时b
,在循环的下一次迭代中,它将立即找到一个新的替换匹配项并b
(最初a
)交换回a
.
只需打印替换循环的状态即可轻松查看:
c=b a=a
c=b a=b
c=a a=c
c=a a=d
c=a a=e
c=a a=f
c=a a=g
c=a a=h
c=a a=i
c=a a=j
c=a a=k
c=a a=l
c=a a=m
c=a a=n
c=a a=o
c=a a=p
c=a a=q
c=a a=r
c=a a=s
c=a a=t
c=a a=u
c=a a=v
c=a a=w
c=a a=x
c=a a=y
c=a a=z
c=o a=a
c=o a=b
c=o a=c
c=o a=d
c=o a=e
c=o a=f
c=o a=g
c=o a=h
c=o a=i
c=o a=j
c=o a=k
c=o a=l
c=o a=m
c=o a=n
c=o a=o
c=p a=p
c=o a=q
c=o a=r
c=o a=s
c=o a=t
c=o a=u
c=o a=v
c=o a=w
c=o a=x
c=o a=y
c=o a=z
c=b a=a
c=b a=b
c=a a=c
c=a a=d
c=a a=e
c=a a=f
c=a a=g
c=a a=h
c=a a=i
c=a a=j
c=a a=k
c=a a=l
c=a a=m
c=a a=n
c=a a=o
c=a a=p
c=a a=q
c=a a=r
c=a a=s
c=a a=t
c=a a=u
c=a a=v
c=a a=w
c=a a=x
c=a a=y
c=a a=z
c = chars[i]
, a = alpha[j]
. 在c=b
您可以看到替换很快完成,然后我们无缘无故地继续进行,但是在 上c=o
,您可以看到它到达a=o
,翻转到c=p
但在那个点a=p
所以我们翻转回c=o
。
通过使用stg
来检查这不是一个因素,因为原始数据没有被翻转。另一种方法是break
在您找到alpha[j]
匹配的 a之后chars[i]
。
该脚本似乎过于复杂:
- 您正在检查中
cap_alpha
进行检查alpha
,因为这些集合是不重叠的,我看不出它怎么能做一些有用的事情。 - try/except 似乎没有用?我本可以看到一个模数问题,但是在你的方案
z
中被交换了y
所以没有任何有趣的事情发生
更重要的是,您没有使用 Python 的工具,例如string
已经提供了字母表,str.translate
可以采用转换表,list.index
将返回列表中项目的索引(但是当它没有找到任何东西时会引发异常,这str.find
很方便,因为它然后返回None
),chr
并将ord
从代码点数字转换为代码点数字,您可以使用位操作来翻转数字,...
您可能可以使用位旋转来做到这一点(它甚至可能很有趣),但作为第一个近似值,我只是构建一个翻译表并使用str.translate。这不是最容易掌握的东西,但一旦你掌握它就很方便:
# str.maketrans can take various formats to build the translation
# table. Here we're going to use the simplest, a dictionary mapping
# unicode ordinals (letter codes) to other unicode ordinals, the
# mapping is the transformation we want to define
tr = {}
# iterate on the codes of "odd" letters (a, c, e, g, ...) and create
# the entries to map both forward (a -> b) and backwards (b -> a)
for letter in range(ord('a'), ord('z'), 2):
tr[letter] = letter+1
tr[letter+1] = letter
# repeat for uppercase
for letter in range(ord('A'), ord('Z'), 2):
tr[letter] = letter+1
tr[letter+1] = letter
table = str.maketrans(tr)
def easyCryto(stg=''):
return stg.translate(table)
print(easyCryto('Willy'))
推荐阅读
- php - 网站无法上传主题,需要增加PHP
- r - 无法使用 R 3.6 在 ubuntu 18.04 中安装 phytools
- python - 使用 pyodbc 从 SQLAlchemy 连接到 Oracle 数据库
- python - 从 GoogleSheet 创建 Google BigQuery 表
- python - Flutter -> Flask SocketException(SocketException:操作系统错误:连接被拒绝,errno = 111,地址 = 127.0.0.1,端口 = 50484)
- python - 想从不同国家发送请求获取python
- python - Python Sqlite3 TypeError:“NoneType”对象不可下标
- c++ - 重载运算符 C++,复数?
- c++ - 如何读取 TXT 文件并在 C 中仅存储 int
- php - 尝试在 Laravel Ubuntu Nginx 服务器上上传图像