这是混淆代码的有效方法吗?它是否性能友好?

时间:2014-06-29 15:05:15

标签: java obfuscation performance deobfuscation

所以我最近想到了一种方法可以使代码去混淆变得更加困难。但我不确定这是否会对我的代码性能产生负面影响:所以我的想法就是转换代码:

public class SpeedTest1 {

public static void main(String[] args){
    long start = System.currentTimeMillis();

    String toEncode = "fhsdakjfhasdkfhdsajkhfkshfv ksahyfvkawksefhkfhskfhkjsfhsdkfhjfhskjhafjkhskjadfhksdfhkjsdhfksfhksdhfsdyfieyt893489ygfudhgiueryriohetyuieyiuweatiuewytiueaytuiwfytwuiediuvnhuighsiudghfjdkghfsdkjghdiugfdkghdkjghdfkghfdghdigyeuriyeibuityeuirtuireytiuerythgfdkgiuegduigkghfdjkghjgkdfhgjfdhgjfdghfdkjghfdjkghfdkjghfdjkgfdjkghfdkjghfdjkgfdkjghfdkjgheriytretyretrityreiutyeriuhslfjlflkfflksdjflkjflks";
    String str = Base64.encode(toEncode.getBytes());
    try {
        System.out.println(new String(Base64.decode(str), "UTF-8"));
    } catch (Base64DecodingException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    long end = System.currentTimeMillis();
    System.out.println("Time: " + (end - start));
}
}

进入此代码:

public class SpeedTest2 {

public static void main(String[] args){
    long start = System.currentTimeMillis();

    System.out.println(y(x(z(a().getBytes()))));

    long end = System.currentTimeMillis();
    System.out.println("Time: " + (end - start));
}

private static String y(byte[] b){
    try {
        return new String(b, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

private static byte[] x(String s){
    try {
        return Base64.decode(s);
    } catch (Base64DecodingException e) {
        e.printStackTrace();
    }
    return null;
}

private static String z(byte[] b){
    return Base64.encode(b);
}

private static String a(){
    return "fhsdakjfhasdkfhdsajkhfkshfv ksahyfvkawksefhkfhskfhkjsfhsdkfhjfhskjhafjkhskjadfhksdfhkjsdhfksfhksdhfsdyfieyt893489ygfudhgiueryriohetyuieyiuweatiuewytiueaytuiwfytwuiediuvnhuighsiudghfjdkghfsdkjghdiugfdkghdkjghdfkghfdghdigyeuriyeibuityeuirtuireytiuerythgfdkgiuegduigkghfdjkghjgkdfhgjfdhgjfdghfdkjghfdjkghfdkjghfdjkgfdjkghfdkjghfdjkgfdkjghfdkjgheriytretyretrityreiutyeriuhslfjlflkfflksdjflkjflks";
}
}

现在第二部分更难以弄清楚它的作用。但现在我担心我的程序的性能,所以我添加了检查时间线,看​​看两者中的一个是否比另一个更快。现在大部分时间他们都打印0作为时间,但有时两个打印中的一个打印像15,但从来没有相同的方法。我确实找到了这个答案[java how expensive is a method call,它表明Java本身在运行时优化了代码,这意味着使用两个例子并不重要吗?因为它们在执行时都是平等的。所以我现在想知道这是一种混淆代码的好方法,还是会对代码效率产生负面影响?

1 个答案:

答案 0 :(得分:2)

关于一般的混淆:

1)反对你想保护什么?

1.1)Java初学者理解你的代码:你的方法可能没问题

1.2)Java专家了解您的代码:您的方法确实无法正常工作,甚至可能不会使专家减速超过因子2

1.3)竞争对手了解您的代码:您的方法确实无法运作,竞争对手可能会投入大量资源来完成任务

2)您是否必须稍后维护代码?

2.1)是:您需要将原始资源转换为混淆变体的内容(见下文)

2.2)否:你可能没问题,但是,如果你以后需要修复一个bug,你可能不会理解你之前创建的内容(即使有文档代码,它也会经常发生在专家身上...... )

混淆工具:

话虽如此,您可能需要查看ProGuardhttp://proguard.sourceforge.net)。它是一个Java混淆器,它甚至可以提高低资源平台的性能(主要是通过缩短类名和包名以及减少类文件的大小来推动)。

有加密类加载器。这给你的对手带来了困难,但你不会安全 - 请参阅this article

关于效果:

无论您是否进行了更改,都必须运行性能测试。您需要在最终运行软件的平台上执行此操作。有些代码肯定更慢,有些代码肯定更快 - 但是,最终你需要测试它。