避免在Python IRC bot中进行昂贵的计算

时间:2012-07-14 19:34:21

标签: python calculator arbitrary-precision

我在公共IRC机器人中使用this calculator。鉴于Python默认使用任意精度,这将允许任何用户执行calc 10000**10000**10000calc factorial(1000000)之类的操作并有效地“杀死”机器人。

我想知道的是,是否有某种方法可以避免这种情况。我已经尝试将表达式中的所有术语转换为float,但float(factorial(1000000)仍然需要很长时间才能完成Python解释器,而且我不确定多线程方法是否是正确的方法。< / p>

2 个答案:

答案 0 :(得分:2)

不是真正的答案,但我会这样做。您要运行的所有内容都应该在不同的进程中运行。据我所知,不可能限制进程中单个线程的CPU使用率或内存使用量。

也就是说,你必须创建一个新的进程,就像执行用户输入的任务一样,将其写入文件例如。您可以使用fork执行此操作,使用PID创建新文件,主进程必须检查,直到子进程终止。一旦进程终止,打开文件“cool_calculator_ [pid] .out”并将其发送回IRC

我想这很简单。

然后使用ulimit或其他工具,您可以限制子进程,甚至可以使用主进程终止它们。如果pid的文件为空,只需回答有错误或其他内容。我想你甚至可以写出一些错误,如超出内存或超出cpu等。

这一切都取决于你想要如何杀死坏的进程。

最后,你的主进程将有工作来生成孩子并在需要时杀死他们并发回答案。

答案 1 :(得分:1)

看起来float()演员阵容毕竟是解决方案。

首先,反三角函数不会取其域外的值,因此它们是完全安全的,并且可以捕获异常。

>>> acos(5e100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

fmod()函数也会发生同样的事情。

“正常”三角函数似乎对大值没有任何问题,除非它们真的大,这使得函数再次返回ValueError

舍入函数(ceil()floor()round())工作正常,如果值太大则返回inf。同样适用于degrees()log()log10()pow()sqrt()fabs()hypot()和{{1函数。

双曲三角函数和radians()函数抛出exp()或返回OverflowError

inf函数可以很好地处理大值。

对于简单的算术运算,float cast使函数抛出atan2()(或OverflowError)而不是进行计算。

inf

最后,有问题的factorial()函数。我所要做的就是以迭代的方式重新定义函数并将其添加到>>> float(10) ** float(100) ** float(100) ** float(1000) Traceback (most recent call last): File "<stdin>", line 1, in <module> OverflowError: (34, 'Numerical result out of range') >>> float(5e500) * float(4e1000) inf

safe_dict

虽然这是计算阶乘的一种非常丑陋且极其低效的方式,但它足以满足我的需求。事实上,我认为我添加了许多不必要的import sys def factorial(n): fact = 1 while (n > 0): fact = float(fact) * float(n) n -= float(1) if float(fact) > sys.float_info.max: return "Too big" return str(fact) print factorial(50e500) s。

现在我需要弄清楚如何将float()放在表达式中的所有术语周围,这样就会自动发生。