All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.crashnote.core.util.ChksumUtil Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/**
 * Copyright
 *
 * We compute the checksum using Broder s implementation of
 * Rabin s fingerprinting algorithm. Fingerprints offer
 * provably strong probabilistic guarantees that two
 * different strings will not have the same fingerprint.
 * Other checksum algorithms, such as MD5 and SHA, do not
 * offer such provable guarantees, and are also more
 * expensive to compute than Rabin fingerprint.
 * 

* A disadvantage is that these faster functions are * efficiently invertible (that is, one can easily build an * URL that hashes to a particular location), a fact that * might be used by malicious users to nefarious purposes. *

* Using the Rabin's fingerprinting function, the probability of * collision of two strings s1 and s2 can be bounded (in a adversarial * model for s1 and s2) by max(|s1|,|s2|)/2**(l-1), where |s1| is the * length of the string s1 in bits. *

* The advantage of choosing Rabin fingerprints (which are based on random * irreducible polynomials) rather than some arbitrary hash function is that * their probability of collision os well understood. Furthermore Rabin * fingerprints can be computed very efficiently in software and we can * take advantage of their algebraic properties when we compute the * fingerprints of "sliding windows". *

* M. O. Rabin * Fingerprinting by random polynomials. * Center for Research in Computing Technology * Harvard University Report TR-15-81 * 1981 *

* A. Z. Broder * Some applications of Rabin's fingerprinting method * In R.Capicelli, A. De Santis and U. Vaccaro editors * Sequences II:Methods in Communications, Security, and Computer Science * pages 143-152 * Springer-Verlag * 1993 */ package com.crashnote.core.util; import java.io.Serializable; public final class ChksumUtil implements Serializable { // INTERFACE ================================================================================== /** * Computes the Rabin hash value of a String. * * @param s the string to be hashed * @return the hash value */ public static long hash(final String s) { return hash(s.toCharArray()); } // INTERNALS ================================================================================== private final static int P_DEGREE = 64; private final static int X_P_DEGREE = 1 << (P_DEGREE - 1); private static final long POLY = Long.decode("0x004AE1202C306041") | 1 << 63; private static final long[] table32, table40, table48, table54; private static final long[] table62, table70, table78, table84; static { table32 = new long[256]; table40 = new long[256]; table48 = new long[256]; table54 = new long[256]; table62 = new long[256]; table70 = new long[256]; table78 = new long[256]; table84 = new long[256]; final long[] mods = new long[P_DEGREE]; mods[0] = POLY; for (int i = 0; i < 256; i++) { table32[i] = 0; table40[i] = 0; table48[i] = 0; table54[i] = 0; table62[i] = 0; table70[i] = 0; table78[i] = 0; table84[i] = 0; } for (int i = 1; i < P_DEGREE; i++) { mods[i] = mods[i - 1] << 1; if ((mods[i - 1] & X_P_DEGREE) != 0) { mods[i] = mods[i] ^ POLY; } } for (int i = 0; i < 256; i++) { long c = i; for (int j = 0; j < 8 && c != 0; j++) { if ((c & 1) != 0) { table32[i] = table32[i] ^ mods[j]; table40[i] = table40[i] ^ mods[j + 8]; table48[i] = table48[i] ^ mods[j + 16]; table54[i] = table54[i] ^ mods[j + 24]; table62[i] = table62[i] ^ mods[j + 32]; table70[i] = table70[i] ^ mods[j + 40]; table78[i] = table78[i] ^ mods[j + 48]; table84[i] = table84[i] ^ mods[j + 56]; } c >>>= 1; } } } /** * Return the Rabin hash value of an array of chars. * * @param A the array of chars * @return the hash value */ private static long hash(final char[] A) { long w = 0; final int start = A.length % 4; for (int s = 0; s < start; s++) { w = (w << 16) ^ (A[s] & 0xFFFF); } for (int s = start; s < A.length; s += 4) { w = table32[(int) (w & 0xFF)] ^ table40[(int) ((w >>> 8) & 0xFF)] ^ table48[(int) ((w >>> 16) & 0xFF)] ^ table54[(int) ((w >>> 24) & 0xFF)] ^ table62[(int) ((w >>> 32) & 0xFF)] ^ table70[(int) ((w >>> 40) & 0xFF)] ^ table78[(int) ((w >>> 48) & 0xFF)] ^ table84[(int) ((w >>> 56) & 0xFF)] ^ ((long) (A[s] & 0xFFFF) << 48) ^ ((long) (A[s + 1] & 0xFFFF) << 32) ^ ((long) (A[s + 2] & 0xFFFF) << 16) ^ ((long) (A[s + 3] & 0xFFFF)); } return w; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy