2012-07-14 31 views
2

我在公共IRC bot中使用this calculator。鑑於Python默認使用任意精度,這將允許任何用戶執行諸如calc 10000**10000**10000calc factorial(1000000)之類的操作並有效「殺死」bot。避免在Python中進行昂貴的計算IRC bot

我想知道的是如果有某種方法可以避免這種情況。我已經嘗試將表達式中的所有術語都轉換爲float,但float(factorial(1000000)仍然需要很長時間才能在Python解釋器中完成,而且我不確定多線程方法是否是正確的方式。

+0

我知道它使用'eval',但我試圖長時間執行危險的命令,我什麼也做不了。我知道這並不能保證它是100%安全的,但是將要使用的用戶是「半可信」的,這意味着他們不會用'os'做出奇怪的事情,但我相信他們會殺死有趣的機器人。 – user1002327 2012-07-14 20:01:17

+0

下面是計算器的實際代碼,我使用那個僅用於提出問題的簡短代碼。 http://pastebin.com/auF1krdh – user1002327 2012-07-14 20:02:15

+0

不知道python我想你需要像Loic之一的方法:啓動計算器作爲獨立的進程,並在指定的時間後殺死它。我擔心通過使用factorial等函數幾乎不可能強制用戶只插入快速可計算的輸入,但在腳中拍攝計算器的方法太多了。 – 2012-07-14 20:13:10

回答

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()radians()功能相同。

雙曲三角函數和exp()函數拋出OverflowError或返回inf

atan2()功能工作完美罰款與大值。

對於簡單的算術運算,浮點投球使函數拋出OverflowError(或inf)而不是進行計算。

>>> 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 

最後,有問題的factorial()函數。我所要做的就是以迭代方式重新定義函數,並將其添加到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) 

雖然這是一個非常醜惡的,非常低效的計算因子的方法,但對我的需求來說已經足夠了。其實我覺得我加了很多不必要的float() s。

現在我需要弄清楚如何將float() s放在表達式中的所有術語中,所以這會自動發生。

2

不是一個真正的答案,但我會這樣做。你要運行的所有東西都應該在不同的過程中運行。據我所知,無法限制進程中單個線程的CPU使用率或內存使用率。

也就是說,您必須創建一個新的進程,與任務一樣執行用戶輸入的內容,並將其寫入文件以供例證。你可以用fork來做到這一點,使用PID創建一個新文件,並且主進程必須檢查,直到子進程死亡。一旦進程死亡,打開文件「cool_calculator_ [pid] .out」並將其發送回IRC

很簡單,我猜。

然後使用ulimit或其他工具,可以限制子進程,甚至使用主進程殺死它們。如果pid的文件是空的,只需回答出現錯誤或其他內容。我猜你甚至可以寫出一些錯誤,如超出內存或超出CPU等。

這一切都取決於你想如何殺死壞的進程。

最後,你的主進程將有工作產卵孩子,如果需要殺死他們併發回答案。

+0

噢,因爲我在C中遇到了溢出的各種錯誤,我想知道是否檢測到溢出Python是可能的,正如我之前所說的,將所有東西都轉換成浮動是不夠的,但它解決了很多問題。'float(10000)** float(9999999999)'thro '浮動(階乘(12000))',但由於某種原因'浮動(階乘(120000))'試圖完成整個計算。 – user1002327 2012-07-14 19:59:18

+1

'float(factorial(120000))* *拋出一個OverflowError,它只需要一段時間。在計算階乘之後發生OverflowError *。 – DSM 2012-07-14 20:06:21

+0

哦,我沒有讓它完成,因爲我認爲這會花更長的時間。感謝您指出了這一點。 – user1002327 2012-07-14 20:07:38

相關問題