我正在编写一个安全系统,拒绝未经授权的用户访问。
name = input("Hello. Please enter your name: ")
if name == "Kevin" or "Jon" or "Inbar":
print("Access granted.")
else:
print("Access denied.")
它按预期授予授权用户访问权限,但也允许未经授权的用户进入!
Hello. Please enter your name: Bob
Access granted.
为什么会发生这种情况?我已经明确声明,只有在 name
等于凯文、乔恩或英巴。我也试过相反的逻辑, if "Kevin" or "Jon" or "Inbar" == name
,但结果是一样的。
注意:这个问题旨在作为这个非常常见问题的标准复制目标。还有一个流行的问题,如何针对单个值测试多个变量?这有着同样的根本问题,但比较目标是相反的。这个问题不应该重复这个问题,因为这个问题是python新手遇到的,他们可能很难将反向问题中的知识应用到他们的问题中。
5条答案
按热度按时间dxpyg8gm1#
在许多情况下,python的外观和行为类似于自然英语,但这是抽象失败的一种情况。人们可以使用上下文线索来确定“jon”和“inbar”是连接到动词“equals”的对象,但python解释器更注重文字。
逻辑上等同于:
对于用户bob,这相当于:
这个
or
运算符选择具有正真值的第一个参数:既然“jon”有一个积极的真值
if
块执行。这就是为什么不管给定的名称如何,都会打印“已授予访问权限”。所有这些推理也适用于表达式
if "Kevin" or "Jon" or "Inbar" == name
. 第一个值,"Kevin"
,是真的,所以if
块执行。有两种常见的方法可以正确构造此条件。
使用多个
==
要显式检查每个值的运算符:组成有效值的集合(例如,集合、列表或元组),并使用
in
要测试成员资格的操作员:一般而言,应优先选择第二种,因为它更容易阅读,也更快:
对于那些可能需要证据的人
if a == b or c or d or e: ...
确实是这样解析的。内置的ast
模块提供了一个答案:可以看出,这是布尔运算符
or
应用于四个子表达式:比较a == b
; 和简单的表达c
,d
,及e
.oknrviil2#
中有3个条件检查
if name == "Kevin" or "Jon" or "Inbar":
姓名==“凯文”“乔恩”
“inbar”
这个if语句等价于
自从
elif "Jon"
将始终为true,因此授予对任何用户的访问权限解决方案
您可以使用下面的任何一种方法
快速的
缓慢的
慢+不必要的代码
fcg9iug33#
简单的工程问题,让我们更进一步。
但是,python继承了c语言,将非零整数的逻辑值计算为true。
现在,python构建在该逻辑的基础上,并允许您使用逻辑文本,例如或整数,等等
最后
正确的书写方式是:
为了安全起见,我还建议你不要硬编码密码。
shyt4zoc4#
非空列表、集合、字符串等是可计算的,因此返回true。
因此,当你说:
你实际上是在说:
因为“john”和“inbar”中至少有一个不是空字符串,所以整个表达式始终返回true!
解决方案:
或:
kmbjn2e35#
接近
数据科学家如何处理这个问题
最简单的方法是不需要比较运算符,而是使用列表。这在安全系统上看起来令人印象深刻,因为您学会了访问orms。
或者,您可以使用与上面完全相同的代码,只需将注册用户列表放入他们自己的列表中:
如果希望安全地完成此协议而不存在攻击风险,请设置双参数。这将检查您的迷你orm的
first
及last
名称字段以及password
或secret question
钥匙如果要在不进行散列的情况下高效地延迟加载用户凭据,可以按如下方式对对象进行排序:循环将仅消耗生成的值,以节省系统上的时间和精力:
然后可以使用迭代列表执行以下操作:
这个问题可以从任何Angular 来解决:内存管理、安全性,或者仅仅通过一个有机列表或打包的orm。
希望这有帮助。