5

I am currently throwing an obfuscation program for school homework together. I am trying to make the program read a file and then create a new file that replaces each letter in the file with some a corresponding value that I pull from a HashMap. I set up a whole bunch of keys and values, but later in the process of writing the new file I try to check if the map contains a key before appending to the new String. The characters that are checked are in fact in the file that I am reading from to test, and the file is read correctly. Yet it fails with the encryptionDict.containsKey() (my hashmap) method.

I hope some Java expert can help me figure this out! I'm pretty clueless, I'm more of a C and D guy. The only thought that struck me was that it would be something like with Strings where "foo" != "foo". But chars aren't objects.

The code is in a pastebin below, the key parts to look at is the class constructor, the method encrypt, and the method initDictionary, also can someone tell me why HashMap<char, String> is invalid, is it because I have to use an object?

The code: http://pastebin.com/NcHTHPfw

4

4 回答 4

6
 private HashMap<char [], String> initDictionary() {
                HashMap<char [], String> d = new HashMap<char [], String>();

                d.put("a".toCharArray(), "!\"#¤");
                d.put("b".toCharArray(), "¤#\"!");
                d.put("c".toCharArray(), "\"#¤%");
                d.put("d".toCharArray(), "%¤#\"");
                d.put("e".toCharArray(), "#¤%&");
                d.put("f".toCharArray(), "&%¤#");
                d.put("g".toCharArray(), "¤%&/");
                d.put("h".toCharArray(), "/&%¤");
                d.put("i".toCharArray(), "%&/(");
                d.put("j".toCharArray(), "(/&%");
                d.put("k".toCharArray(), "&/()");
                d.put("l".toCharArray(), ")(/&");
                d.put("m".toCharArray(), "/()=");
                d.put("n".toCharArray(), "=)(/");
                d.put("o".toCharArray(), "()=?");
                d.put("p".toCharArray(), "?=)(");
                d.put("q".toCharArray(), ")=?!");
                d.put("r".toCharArray(), "!?=)");
                d.put("s".toCharArray(), "=?!\"");
                d.put("t".toCharArray(), "\"!?=");
                d.put("u".toCharArray(), "?!\"#");
                d.put("v".toCharArray(), "#\"!?");
                d.put("w".toCharArray(), ";:*^");
                d.put("x".toCharArray(), "^*:;");
                d.put("y".toCharArray(), ":*^>");
                d.put("z".toCharArray(), ">^*:");
// etc.

这是有问题的一点。您不能在 Java 中使用数组作为哈希键,因为 Array 不会覆盖 equals() 和 hashCode() 方法。

hashCode 用于查找包含您要查找的对象的正确存储桶,equals() 方法比较实际的对象。要使用 HashMap,您需要以合理的方式覆盖这两个方法,因为数组类是最终的,所以您不能这样做。因此,如果您绝对坚持使用 char 数组,您唯一能做的就是使用包装类作为具有 char 数组的键。

像这样的东西:

public class Key {
    private final char[] array;

    public Key(final String string) {
        this(string.toCharArray());
    }
    public Key(final char[] array) {
        this.array = array;
    }

    public char[] getArray() {
        return array;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Key key = (Key) o;

        if (!Arrays.equals(array, key.array)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return array != null ? Arrays.hashCode(array) : 0;
    }
}

现在您可以从 a或 a获得 aMap<Key, String>和 bould 一个Key对象Stringchar[]

于 2012-09-11T14:02:02.550 回答
2

问题是所有char[]内容都是独一无二的,无论其内容如何。看来您真的想使用字符串。通常,您可以编写这样的程序,而无需使用char[]

相反,你可以写

private Map<Character, String> initDictionary() {
Map<Character, String> d = new HashMap<Character, String>();

d.put('a', "!\"#¤");
// etc
于 2012-09-11T14:02:41.027 回答
0

不要使用数组作为键,它们不可比较,所以比较时值不匹配

于 2012-09-11T14:03:47.093 回答
0

您正在使用HashMap<char [], String>. 这不起作用.equals.hashCode也没有在数组上定义。这个简单的测试程序验证了这一点:

public static void main(String[] args) {
  char[] a = String.valueOf('a').toCharArray();
  char[] b = String.valueOf('a').toCharArray();

  System.out.println(a.hashCode() == b.hashCode());
}

您可以将 aMap<Character, String>用于您的目的。另一种解决方案是使用索引的数组 String[MAX_INDEX] filecontent.charAt(index)- 如果 MAX_INDEX 在您的情况下很小(如“z”),这可能会更简单。

于 2012-09-11T14:10:11.290 回答