在Python中使用黑名单和白名单进行字符串处理

加斯泰尔

我正在创建一个程序,并且需要创建一个逻辑来处理eval()函数的用户输入。输入将是一个数学函数,我想处理一些异常情况,并确保该字符串是一个数学函数,而不是恶意代码。

为此,我创建了一个将字符串的所有字符与黑名单和白名单进行比较的逻辑,问题是该字符串只能以特定排列包含几个字符,例如cos,字符串不能包含c + o * s

whitelist = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '(', ')',
            'x', 'y', 'sin', 'cos', 'tg', '+', '-', '*', '/', ' ']

blacklist = ['a', 'b', 'd', 'f', 'h', 'i', 'j', 'k', 'l', 'm', 'p', 'q',
            'r', 'u', 'v', 'w', 'z']

def stringTreat(string):
    if not any(ch in string for ch in blacklist):
        if all(ch in whitelist for ch in string):
            print('OK!!')
        else:
            print('stop at whitelist')
    else:
        print('stop at blacklist')

string = input('input:')

stringTreat(string)

如果将12 + 67 - 82本例的输入设置为,则输出为OK!!,但是如果cos(x)输入为,则输出更改为stop at whitelist

如何创建逻辑来接受子字符串(例如,(sin,cos,tg),字符(例如,0、1、2、3 ...)),而不接受其他子字符串和字符,例如(a,f,@,$ ,ls,mv)?

ner

您尝试构建的内容通常称为解析器,对于该解析器,可能会发现许多已建立的算法很有用(考虑查看ply软件包)。

通常,这分为两个步骤:标记符和语法。标记器将输入字符串分成多个部分,并可能用一些额外的信息标记它们(例如,12 + cos(3)可能变为[NUM(12), OP(+), FUNC(cos), LPAREN, NUM(3), RPAREN])。请注意,您可以使用如下正则表达式构建非常简单的令牌生成器:

In [1]: re.split(r'\b', '12 + 16 - cos(2)')
Out[1]: ['', '12', ' + ', '16', ' - ', 'cos', '(', '2', ')']

In [2]: [v.strip() for v in re.split(r'\b', '12 + 16 - cos(2)') if v.strip()]
Out[2]: ['12', '+', '16', '-', 'cos', '(', '2', ')']

语法然后寻找标记的模式,并可以告诉它们如何处理,通常将它们形成某种“语法树”,稍后可以更容易地对其进行操作。例如,您可能会将整个函数视为一个一元表达式EXPR(cos, NUM(3)),然后将加法运算视为另一个二进制表达式EXPR(add, NUM(12), EXPR(cos, NUM(3)))请注意,这棵树现在很简单:遇到表达式时,请查看第一个位置的运算符(“ add”,“ cos”等),然后使用该运算符来处理其余的操作数。这些可以递归处理,因此内部表达式可解析为某个数字,然后外部表达式可将其用于解析为最终的单个数字。

您不必那样做,但是拥有这种背景表明,与其像尝试那样一次性完成所有工作,不如先尝试使用令牌生成器,然后再使用一些令牌STR(cos)STR(ls),就可以轻松识别前者作为有效输入,如果遇到另一个(或白名单中未包含的其他任何东西),则会引发错误。

作为一个侧面说明,你一般只能有两种白名单或黑名单,不能同时使用。白名单通常假定其他任何东西都是无效的,而黑名单则假定其他任何东西都是有效的,因此,如果某物落入两个列表中或两个都不属于列表中,则两者同时出现都会带来问题。

最后一点,由于您使用的是Python,因此请谨慎使用,eval并且可以使用一般的Python语法,然后可以使用exec为您执行解析和执行。例如:

In [1]: import math

In [2]: eval('12 + 16 - cos(2)', {'cos': math.cos}, {})
Out[2]: 28.416146836547142

您可以在这些词典中指定希望用户访问哪些功能,并阻止它们与程序状态下的任何其他事物进行交互。除非您对用户至少有一点信任,或者他们只能通过搞砸自己而伤害自己,否则我可能还是不会这样做。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

SSH的白名单和黑名单

XSS的黑名单/白名单

当两者部分重叠时如何匹配白名单中的字符串而不是黑名单中的字符串

错误:使用原因字符串“黑名单:帐户被列入黑名单”恢复

PhpStorm中的代码覆盖白名单/黑名单

具有黑名单(排除)和白名单(包含)的Powershell复制文件

我可以在Artifactory中实施白名单和/或黑名单吗?

按多个标签选择(白名单和黑名单)

如何在discord.py中将用户列入黑名单和白名单?

PHPUnit的白名单和黑名单似乎被忽略了

在熊猫python中,我如何在DataFrame中“黑名单”或“白名单”数字

使用白名单对象验证 url 字符串

在树枝中使用一个功能,例如striptag,但我想将标签列入黑名单,而不是白名单标签

字符串中的PHP黑名单单词

是否有一个(开放源代码)VCS可以使用白名单而不是黑名单?

启用/禁用每个站点的Chrome扩展程序(通过白名单或黑名单)

如何在@RequestBody中将参数列入白名单/黑名单

iOS mobileconfig-应用程序黑名单/白名单?

增加效率我的IP黑名单白名单脚本

如何将数组转换为 snips-nlu-rs 白名单或黑名单?

确实需要白名单/黑名单/主题之一

IIS重定向白名单查询字符串

从黑名单和白名单正则表达式表达式创建正则表达式以标识和删除url参数

Linux权限:用户,组,其他,白名单还是黑名单?并帮助共享具有完全,部分和无权限的目录

从其他两个表(黑名单和白名单查询)填充第三个表(sqlite)

使用多个正则表达式检查字符串中是否存在列入黑名单的模式

检查网址是否包含列入黑名单的字符串

从字符串中删除列入黑名单的术语,然后消除不必要的空格

从字符串中删除所有不在白名单中的字符