【问题标题】:Compare Code Submissions with Previous Submissions?将代码提交与以前的提交进行比较?
【发布时间】:2013-11-12 04:26:45
【问题描述】:

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

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

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

【问题讨论】:

  • 你更关心编译时间还是执行时间?根据语言,您可以存储编译后的字节码。
  • 根据您的安全要求,这可能构成信息泄露漏洞;攻击者可以判断其他人是否提交了特定样本。这可能不是问题。
  • @SLaks,整个过程需要时间,所以我需要比较源代码,而不是字节码。信息披露在我的网站上不是问题。谢谢。
  • 您可以将源代码映射到字节码
  • 如果您想比较代码并检测以简单方式不同的情况(例如,变量被重命名),您需要一个了解代码结构的工具,什么是重要的(例如,不是空格)以及如何仅基于语言结构来检测差异。 “差异”不理解代码;它只理解线条,因此效果不佳。您可以查看我公司的 SmartDifferencer 源代码差异工具,该工具使用完整的解析器执行此操作,只关注结构上的差异。 SO不希望我发布链接;你必须仔细阅读我的简历。

标签: java ruby-on-rails database optimization static-analysis


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 谢谢,我看看哈希是否有意义。我实际上正在使用 Ideone,这有时需要很长时间!
  • 我可以用简化的代码和 add_index 创建另一个表,这样可以快速查找。
  • @Ari:如果存储没问题,在混淆前后都运行哈希。散列的速度要快得多,因此您可以节省混淆时间(如果幸运的话)。
【解决方案2】:

变量名称:
您可以编写代码将一个文件中的变量名称与另一个文件中的变量名称匹配,然后您可以将这两个集合替换为一致的变量名称。

文件 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....   

这些只是我能想到的几种方式。如果你这样做,它最终会成为一个相当大的项目......尤其是如果你使用多种语言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    相关资源
    最近更新 更多