我只是想知道(在一些严重的偏执和某些情况下)使用 QuickSort 算法是否会被视为应用程序中的安全风险。
它的基本实现和改进版本(如3-median-quicksort)都具有特定输入数据行为异常的特性,这意味着在这些情况下它们的运行时间会极大地增加( O(n^2)
复杂性)更不用说堆栈溢出的可能性了。
因此,我认为通过向程序提供预先排序的数据可能会造成伤害,导致算法表现得像这样,这可能会导致例如不可预测的后果。一个多客户端Web应用程序。
这个奇怪的案例是否值得任何安全考虑(因此会强迫我们使用简介 - 或 Mergesort )?
编辑:我知道有很多方法可以阻止Quicksort的最坏情况,但是语言集成排序怎么样(比如3-Median of .NET)。它们会成为禁忌吗?
答案 0 :(得分:25)
是的,这是一个安全风险 - DoS,具体而言 - 通过在快速排序中添加对递归深度的检查,以及在达到某个深度时切换到其他内容,可以轻松减轻这种风险。如果你切换到heapsort,那么你将获得introsort,这是许多STL实现实际使用的。
或者,您只需随机选择pivot元素。
答案 1 :(得分:9)
快速排序的许多实现都是使用randomized version of the algorithm完成的。这意味着无法使用特制的输入DoS attack。
此外,即使没有这个,大多数数据集都很简单,太小而不具备O(nlog)与O(n ^ 2)的关系。要进行排序的集合的大小必须非常大才能产生影响。即使有几百万个元素,时差也可能不会很大。
答案 2 :(得分:5)
看一下这个问题(以及标记答案),讨论减少QuickSort最坏情况的方法:
答案 3 :(得分:1)
如果性能很重要,那么在大多数情况下,QuickSort似乎是一个糟糕的选择,安全问题与否。有什么东西会让你回避像Heapsort或Mergesort这样的算法吗?
答案 4 :(得分:1)
我认为这是一个关于你实际使用快速排序的问题。例如,当你使用5个项目的数组时,使用O(n ^ 2)算法是完全正确的。另一方面,当数据可能非常大时,担心DoS不是您将面临的第一个问题 - 第一个问题是在您遇到真正的问题之前会遇到糟糕的性能问题。鉴于可用的大量其他算法,如果它位于关键位置,只需将其替换即可。
答案 5 :(得分:0)
它只是在非常非常不可能的情况下 - 所有这些都很容易被设计合理的算法来避免。
但是如果你想要超级安全,你可能想要使用像Introsort这样的东西,它以QuickSort开头但如果它从递归深度检测到算法开始时切换到堆排序去二次方。
编辑:我看到Pavel把我打败了Introsort。
回应编辑问题:我没有亲自测试过每一个Quicksort库,但我觉得很安全,他们几乎所有人都有检查以避免最坏的情况。