是的,你可以用CRC得到這個效果。
你需要做的是:
- 實現的算法,將找到一個給定的狀態(N位CRC累加器)到另一家領先的N個輸入比特序列。
- 以正常方式計算輸入的CRC。注意最後的狀態(稱之爲A)
- 使用(1)中實現的函數,找出從A到A的位的序列。這個序列就是你的哈希碼。您現在可以將其附加到輸入。
[Initial state] >- input string -> [A] >- hash -> [A] ...
Here is one way to find the hash。 (注意:CRC32示例中的數字存在錯誤,但該算法有效。)
這裏是Java中的一個實現。注意:我使用了32位的CRC(小於你指定的64),因爲它是在標準庫中實現的,但是通過第三方庫代碼,你可以輕鬆地將它擴展到更大的散列值。
public static byte[] hash(byte[] input) {
CRC32 crc = new CRC32();
crc.update(input);
int reg = ~ (int) crc.getValue();
return delta(reg, reg);
}
public static void main(String[] args) {
byte[] prefix = "Hello, World!".getBytes(Charsets.UTF_8);
System.err.printf("%s => %s%n", Arrays.toString(prefix), Arrays.toString(hash(prefix)));
byte[] suffix = hash(prefix);
byte[] combined = ArrayUtils.addAll(prefix, suffix);
System.err.printf("%s => %s%n", Arrays.toString(combined), Arrays.toString(hash(combined)));
}
private static byte[] delta(int from, int to) {
ByteBuffer buf = ByteBuffer.allocate(8);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(from);
buf.putInt(to);
for (int i = 8; i-- > 4;) {
int e = CRCINVINDEX[buf.get(i) & 0xff];
buf.putInt(i - 3, buf.getInt(i - 3)^CRC32TAB[e]);
buf.put(i - 4, (byte) (e^buf.get(i - 4)));
}
return Arrays.copyOfRange(buf.array(), 0, 4);
}
private static final int[] CRC32TAB = new int[0x100];
private static final int[] CRCINVINDEX = new int[0x100];
static {
CRC32 crc = new CRC32();
for (int b = 0; b < 0x100; ++ b) {
crc.update(~b);
CRC32TAB[b] = 0xFF000000^(int) crc.getValue();
CRCINVINDEX[CRC32TAB[b] >>> 24] = b;
crc.reset();
}
}
這個問題,因爲它更符合理論要求,可能是更好的:http://cstheory.stackexchange.com/(姊妹網站) – Orbling 2011-01-28 01:32:45
添加在HTTP一個新職位:// cstheory.stackexchange.com/questions/4609/reflexive-hash-algorithm-exists – henchan 2011-01-28 01:52:03
@henchan,如果你在http://crypto.stackexchange.com上提問,你會得到更好的答案 – Pacerier 2015-05-23 12:36:50