Java 我需要有效地解密文件

Java 我需要有效地解密文件,java,encryption,coding-efficiency,Java,Encryption,Coding Efficiency,我试图用未知密钥解密一个加密文件-我只知道密钥是一个整数x,0如果使用JAVA 8来实现这一点,可以使用JAVA 8中添加的并行数组操作 最适合您的是使用拆分器 public void spliterate() { System.out.println("\nSpliterate:"); int[] src = getData(); Spliterator<Integer> spliterator = Arrays.spliterator(src);


我试图用未知密钥解密一个加密文件-我只知道密钥是一个整数x,0如果使用JAVA 8来实现这一点,可以使用JAVA 8中添加的并行数组操作

最适合您的是使用拆分器

    public void spliterate() {
    System.out.println("\nSpliterate:");
    int[] src = getData();
    Spliterator<Integer> spliterator = Arrays.spliterator(src);
    spliterator.forEachRemaining( n -> action(n) );
}

public void action(int value) {
    System.out.println("value:"+value);
    // Perform some real work on this data here...
}
public void splitrate(){
System.out.println(“\n写入:”);
int[]src=getData();
拆分器拆分器=数组。拆分器(src);
拆分器。forEachRemaining(n->action(n));
}
公共无效操作(int值){
System.out.println(“值:”+value);
//在这里对这些数据执行一些实际工作。。。
}
我还不清楚你的情况。这里有一些很好的教程和文章来说明Java8的哪些并行数组操作将对您有所帮助


如果要使用JAVA 8实现这一点,可以使用JAVA 8中添加的并行数组操作

最适合您的是使用拆分器

    public void spliterate() {
    System.out.println("\nSpliterate:");
    int[] src = getData();
    Spliterator<Integer> spliterator = Arrays.spliterator(src);
    spliterator.forEachRemaining( n -> action(n) );
}

public void action(int value) {
    System.out.println("value:"+value);
    // Perform some real work on this data here...
}
public void splitrate(){
System.out.println(“\n写入:”);
int[]src=getData();
拆分器拆分器=数组。拆分器(src);
拆分器。forEachRemaining(n->action(n));
}
公共无效操作(int值){
System.out.println(“值:”+value);
//在这里对这些数据执行一些实际工作。。。
}
我还不清楚你的情况。这里有一些很好的教程和文章来说明Java8的哪些并行数组操作将对您有所帮助


第一件事:你不能
println
数十亿行。这将花费很长时间,而且毫无意义——当文本滚动经过时,您将无法看到文本,并且您的缓冲区将无法保存数十亿行,因此即使您愿意,您也无法在以后回滚。如果您愿意(并且不介意它比其他方式慢2-3%),您可以每一亿个键输出一次,这样您就可以验证您的程序是否正在进行

您可以通过不在循环中串联字符串来优化内容。字符串是不可变的,因此旧代码创建了大量字符串,特别是在
enc
方法中。通常我会使用
StringBuilder
,但在这种情况下,一个简单的字符数组可以满足我们的需要

还有一件事我们需要做,而您当前的代码没有做:当我们得到答案时检测。如果我们假设消息只包含0-127之间的字符,而不包含Unicode或扩展ASCII,那么当整个消息只包含此范围内的字符时,我们就知道有一个可能的答案。我们还可以使用它来进一步优化,因为我们可以立即丢弃任何字符超出此范围的消息。我们甚至不需要完成解码,就可以进入下一个关键点。(如果消息的长度是任意的,那么很可能只有一个键会生成一条包含该范围内字符的解码消息——但这并不能保证,这就是为什么当我看到一条有效消息时我不会停止。不过,你可能可以这样做。)

由于Java中生成随机数的方式,编码/解码算法不使用32位以上的种子中的任何内容。所以你只需要升到4294967295而不是99999999。(这也意味着最初用于编码消息的密钥可能不是该程序用于解码的密钥,因为10位范围内的2-3个密钥将产生相同的编码/解码。)

private静态字符串tryToDecode4(字符串消息){
字符串returnedString=“”;

对于(long i=0;i第一件事:你不能
println
数十亿行。这将花费永远的时间,而且毫无意义-你将无法在文本滚动时看到它,你的缓冲区将无法保存数十亿行,因此即使你想,你也无法在以后滚动。如果你愿意的话(不要介意它比其他方法慢2-3%),您可以每一亿个密钥输出一次,这样您就可以验证您的程序是否正在进行

您可以通过不在循环中串联字符串来优化内容。字符串是不可变的,因此旧代码创建了大量字符串,特别是在
enc
方法中。通常我会使用
StringBuilder
,但在这种情况下,简单的字符数组可以满足我们的需要

还有一件事我们需要做,而您当前的代码没有做:检测我们何时有答案。如果我们假设消息将只包含0-127之间的字符,没有Unicode或扩展ASCII,那么我们知道当整个消息只包含此范围内的字符时,我们有一个可能的答案。我们还可以使用此方法进一步优化,因为我们可以立即丢弃任何字符超出此范围的消息。我们甚至不需要完成解码,就可以继续下一个键。(如果消息的长度是任意的,那么很可能只有一个键会生成一条包含该范围内字符的解码消息——但这并不能保证,这就是为什么当我看到一条有效消息时我不会停止。不过,你可能可以这样做。)

由于Java中生成随机数的方式,编码/解码算法不使用32位以上的种子中的任何内容。因此,您只需要增加到4294967295,而不是99999999。(这也意味着最初用于编码消息的密钥可能不是该程序用于解码的密钥,因为10位范围内的2-3个密钥将产生相同的编码/解码。)

private静态字符串tryToDecode4(字符串消息){
字符串returnedString=“”;
对于(长i=0;iis)有没有办法使它更有效?-是的:通过知道密钥。你可以依靠字典而不是暴力(即使我认为它在你的场景中不有用),但只要你必须猜测密码,它就不会有效。不要
private static String tryToDecode4(String msg) {
    String returnedString = "";

    for (long i=0; i<=4294967295l; i++)
    {
        if (i % 100000000 == 0) // This part is just to see that it's making progress. Remove if desired for a small speed gain.
            System.out.println("Trying " + i);

        char[] decoded = enc4(msg, i);
        if (decoded == null)
            continue;

        returnedString = String.valueOf(decoded);
        System.out.println("decoding with key: " + i + " " + returnedString);
    }

    return returnedString;
}

private static char[] enc4(String msg, long key) { 
    char[] ansC = new char[msg.length()];
    Random rand = new Random(key); 
    for(int i=0;i<msg.length();i=i+1) 
    { 
        char c = msg.charAt(i); 
        int s = c; 
        int rd = rand.nextInt()%(256*256); 
        int s2 = s^rd; 
        char c2 = (char)(s2); 
        if (c2 > 127)
            return null;
        ansC[i] = c2;
    } 
    return ansC;
}