4

用户在我的网站上提交代码(主要是 java)来解决简单的编程挑战,但将代码发送到服务器进行编译和执行有时可能需要 10 多秒。

为了加快这个过程,我计划首先检查提交数据库,看看之前是否提交过等效代码。我意识到这将导致 Random 方法总是返回相同的结果,但这并不重要。是否有任何其他潜在问题可能是由于不运行代码而导致的?

为了找到匹配项,我在比较代码时删除了注释和空格。但是,相同的代码仍然可以用不同的方式编写,例如使用不同的变量名。有没有办法比较可以找到更多等效代码的代码?

4

2 回答 2

2

您可以存储代码的 SHA1 哈希值以与之前的提交进行比较。你是对的,不同的变量名会给出不同的哈希值。尝试通过压缩器或混淆器运行代码。这样,变量catdog最终都会像a1,那么您可以查看它们是否是唯一的。唯一的另一种方法是将其实际编译成字节码,但为时已晚。

与其分析源代码,不如加快编译速度?尝试让 servlet 容器始终与自定义 ClassLoader 一起运行,并使用 JDK tools.jar 进行即时编译。您甚至可以通过 AJAX REST 提交代码并以相同的方式返回结果。

考虑 Eclipse 如何在后台编译您的文件。

另外,考虑一下http://ideone.com如何实现他们的在线编译器。

仅供参考 允许随机代码执行是一个很大的安全风险。你必须非常小心黑客。

于 2013-11-01T00:52:44.433 回答
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....   

这些只是我能想到的几种方法。如果你这样做,它最终将成为一个相当大的项目......特别是如果你正在使用多种语言。

于 2013-11-01T01:25:36.053 回答