用户在我的网站上提交代码(主要是java)来解决简单的编程挑战,但是将代码发送到服务器进行编译和执行有时需要10秒以上。
为了加快这个过程,我计划先检查提交数据库,看看之前是否提交过等效代码。我意识到这会导致随机方法始终返回相同的结果,但这并不重要。没有运行代码可能导致其他任何潜在问题吗?
要查找匹配项,我会在比较代码时删除注释和空格。但是,相同的代码仍然可以用不同的方式编写,例如使用不同的变量名称。有没有办法比较可以找到更多等效代码的代码?
答案 0 :(得分:2)
您可以存储代码的SHA1哈希值以与之前的提交进行比较。你是对的,不同的变量名称会给出不同的哈希值。尝试通过缩小器或混淆器运行代码。这样,变量cat
和dog
最终都会像a1
一样,然后你可以看到它们是否是唯一的。唯一的另一种方法是将其实际编译为字节码,但那时为时已晚。
为什么不加快编译速度,而不是分析源代码?尝试使用自定义ClassLoader运行servlet容器,并使用JDK tools.jar进行动态编译。您甚至可以通过AJAX REST提交代码并以相同的方式返回结果。
考虑Eclipse如何在后台编译文件。
另外,请考虑http://ideone.com如何实现其在线编译器。
FYI允许随机代码执行是一个很大的安全风险。你必须非常小心黑客。
答案 1 :(得分:1)
变量名称:
您可以编写代码来匹配一个文件中的变量名称和另一个文件中的变量名称,然后您可以用一致的变量名称替换这两个集合。
文件1: var1 + = this(var1 - 1);
文件2: sum + = this(sum - 1);
在阅读文件1之后,您将查找文件2在sum的位置使用的变量名称,然后在两个文件中使变量名称相同。
*注意,如果以类似的方式使用变量,您可能会得到不正确的替换。这很可能是在声明变量时。为了帮助缓解这种情况,您可以开始在文件底部搜索变量名称并进行处理。
短手:
强制{}和()括起来每个if / else / for / while / etc ...
重写操作,如“i + = ...”为“i = i + ...”
功能:
如果函数顺序无关紧要,您可以确保函数是等效的,然后忽略它们。
运营商优先权:
“3 +(2 * 4)”通常相当于“2 * 4 + 3”
解决这个问题的方法可以是确定每个操作的优先级,然后将其与另一组代码中相同优先级的操作相匹配。匹配一组操作后,可以用变量替换它们来表示它们。
实施例
(2+4) * 3 + (2+6) * 5 == someotherequation
//substitute most precedent: (2+4) and (2+6) for a and b
... a * 3 + b * 5
//substitute most precedent: (a*3) and (b*5) for c and d
... c + d
//substitute most precedent....
这些只是我能想到的几种方式。如果你这样做,它最终会成为一个很大的项目...特别是如果你使用多种语言。