【问题标题】:Java Encryption: "java.lang.OutOfMemoryError: Java heap space"Java 加密:“java.lang.OutOfMemoryError:Java 堆空间”
【发布时间】:2016-12-08 16:55:14
【问题描述】:

我正在创建一个能够加密和解密文本的程序。目前,我的加密和解密过程使用 CASE SWITCHES 进行,以避免加密中的任何重叠/错误。我觉得这应该可行。本质上,加密以下列方式工作:FOR 循环读取字符串输入的每个字符,然后将其交给 CASE SWITCH 以替换为某个字符串。我收到以下错误消息:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:541)
    at java.lang.StringBuffer.append(StringBuffer.java:350)
    at java.util.regex.Matcher.appendReplacement(Matcher.java:888)
    at java.util.regex.Matcher.replaceAll(Matcher.java:955)
    at java.lang.String.replaceAll(String.java:2223)
    at OR_v5_12_5_16.main(OR_v5_12_5_16.java:161)

 ----jGRASP wedge2: exit code for process is 1.
 ----jGRASP: operation complete.

这里是代码块的稍微修改和缩短的版本。真正的代码块贯穿所有 26 个大写字符和所有 26 个小写字符。在出现错误消息之前,程序似乎停止了。

for (int i = 0; i < txt.length(); i++){

    String txt_char = String.valueOf(txt.charAt(i));

        switch (txt_char){

            case "A":

                txt = txt.replaceFirst("A", "11110000"); 
                break;
        }
}

【问题讨论】:

  • 您只是将字母“加密”为 1 和 0 的字符串吗?或者您是否也在加密字符'1''0'?如果是这样,当您的循环遇到 '1''0' 时,它将再次扩展所有该字符,生成无限扩展。
  • 不,你刚刚解决了这个问题。 replaceAll 调用是错误的,看起来您正在将字母转换为二进制数字。因此,如果您发布垃圾并被称为垃圾,请不要抱怨。虽然它仍然不是正确的加密,所以你不妨发布 real 代码。
  • 您确实意识到密码分析可以处理比您的monoalphabetic substitution cipher 更复杂的加密。它几乎和你的问题一样弱。
  • 我不知道在任何 Java 环境中您的代码会导致 OOM,除非 txt 已经几乎与分配给 JVM 的所有内存一样大。
  • 只是为了进一步让 OP 学习...您正在创建的是 encoding 而不是加密。它还依赖于“通过默默无闻的安全”,这是一个很大的禁忌。人们用铅笔和纸破解这些编码,他们很容易成为频率分析的受害者,并且根本没有提供实际的安全性。更不用说你正在膨胀 1 字节到 8 字节。在需要真正安全的地方使用它并不明智。

标签: java for-loop encryption switch-statement case


【解决方案1】:

您的加密代码可以通过以下方式变得更有效率:

  • 预分配结果所需的内存
  • 不将单个字符转换回字符串

例子:

StringBuilder result = new StringBuilder(txt.length() * 8);

int len = txt.length();
for (int i = 0; i < len; i++) {
    char ch = txt.charAt(i);

    switch (ch) {
        case 'A': result.append("11110000"); break;
        case 'B': result.append("10101010"); break;
        // ... etc ...
    }
}

txt = result.toString();

通过在加密过程中不修改原始String,也消除了重新加密已加密数据的任何机会。

【讨论】:

  • 谢谢!我一定会试一试的!感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 2010-12-08
  • 2015-05-14
相关资源
最近更新 更多