Java 中的 CRC32 与 pycrc 不同
CRC32 in Java different from pycrc
我试图在 Java 中找到 CRC32 冲突,然后使用 pycrc 检查散列。我尝试了 线程中描述的内容,但我仍然无法使我的实现与 pycrc 匹配。我做错了什么?
public static void print() {
Checksum h = new CRC32();
Map<Long, String> seen = new HashMap<Long, String>();
while (true) {
String s = randomString();
byte[] b = s.getBytes(StandardCharsets.UTF_8);
h.update(b, 0, b.length);
Long l = h.getValue();
if (!seen.containsKey(l)) {
seen.put(l, s);
} else {
System.out.println(s + "; " + seen.get(l));
return;
}
}
}
编辑
经过更多调查,我发现并不是 pycrc 的散列与 Java 的实现不同,而是 Java 只是给我两个具有不同散列的字符串。例如,“93C7946B05”散列为“0xf2792761”,“323C239466”散列为“0x59fc1818”,但是当 Java 比较散列(使用下面的实现)时,它们似乎是 "equal."
更新代码:
static char[] chars = "0123456789ABCDEF".toCharArray();
public static void print() {
Checksum h = new CRC32();
String key;
Map<String, String> seen = new HashMap<String, String>();
while (true) {
String s = randomString();
byte[] b = s.getBytes(StandardCharsets.UTF_8);
h.update(b, 0, b.length);
Long l = h.getValue();
key = Long.toHexString(l);
if (!seen.containsKey(key)) {
seen.put(key, s);
} else {
System.out.println(s + "; " + seen.get(key));
return;
}
}
}
public static String randomString() {
StringBuilder sb = new StringBuilder();
Random random = new Random();
//int len = random.nextInt(32) + 1;
//for (int i = 0; i < len; i++) {
for (int i = 0; i < 10; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
return output;
}
您的问题是您在没有调用 h.reset();
的情况下重新使用了 CRC32 实例。
因此您获得的 CRC32 不是针对当前要测试的字符串,而是针对您目前已测试的所有字符串的连接。
我试图在 Java 中找到 CRC32 冲突,然后使用 pycrc 检查散列。我尝试了
public static void print() {
Checksum h = new CRC32();
Map<Long, String> seen = new HashMap<Long, String>();
while (true) {
String s = randomString();
byte[] b = s.getBytes(StandardCharsets.UTF_8);
h.update(b, 0, b.length);
Long l = h.getValue();
if (!seen.containsKey(l)) {
seen.put(l, s);
} else {
System.out.println(s + "; " + seen.get(l));
return;
}
}
}
编辑
经过更多调查,我发现并不是 pycrc 的散列与 Java 的实现不同,而是 Java 只是给我两个具有不同散列的字符串。例如,“93C7946B05”散列为“0xf2792761”,“323C239466”散列为“0x59fc1818”,但是当 Java 比较散列(使用下面的实现)时,它们似乎是 "equal."
更新代码:
static char[] chars = "0123456789ABCDEF".toCharArray();
public static void print() {
Checksum h = new CRC32();
String key;
Map<String, String> seen = new HashMap<String, String>();
while (true) {
String s = randomString();
byte[] b = s.getBytes(StandardCharsets.UTF_8);
h.update(b, 0, b.length);
Long l = h.getValue();
key = Long.toHexString(l);
if (!seen.containsKey(key)) {
seen.put(key, s);
} else {
System.out.println(s + "; " + seen.get(key));
return;
}
}
}
public static String randomString() {
StringBuilder sb = new StringBuilder();
Random random = new Random();
//int len = random.nextInt(32) + 1;
//for (int i = 0; i < len; i++) {
for (int i = 0; i < 10; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
return output;
}
您的问题是您在没有调用 h.reset();
的情况下重新使用了 CRC32 实例。
因此您获得的 CRC32 不是针对当前要测试的字符串,而是针对您目前已测试的所有字符串的连接。