/// <summary> /// Calculate hamming distance of bits for two fingerprints (normal a fingerprint contains 256 subfingerprints) /// The return value is the Bit Error Rate. /// For 256 subfingerprints a BER lower than 2867 is considered a match /// </summary> public static int HammingDistance(uint[] fingerprint1, uint[] fingerprint2) { if (fingerprint1 == null || fingerprint2 == null) { throw new Exception("fingerprint1 or fingerprint2 is null"); } else if (fingerprint1.Length != fingerprint2.Length) { throw new Exception(string.Format("fingerprint1 and fingerprint2 must be of equal length ({0} != {1})", fingerprint1.Length, fingerprint2.Length)); } // length of both needs to be equal! int BER = 0; // Bit Error Rate for (int i = 0; i < fingerprint1.Length; i++) { int bits = SimilarityUtility.HammingDistance(fingerprint1[i], fingerprint2[i]); if (bits > 0) { BER += bits; } } // for i return(BER); }
/// <summary> /// Creates a lookup dictionary from the fingerprintsignature. Key is the hash an value is an array of int /// pointing (index) to where the hash can be found using "SubFingerprint(int index)" /// </summary> public static Dictionary <uint, int[]> CreateLookupDictionary(FingerprintSignature fs, bool filterNoneRandomHashes = true) { Dictionary <uint, int[]> subFingerLookup = new Dictionary <uint, int[]>(fs.SubFingerprintCount); for (int index = 0; index < fs.SubFingerprintCount; index++) { uint h = BitConverter.ToUInt32(fs.Signature, index * 4); if (filterNoneRandomHashes) { int bits = SimilarityUtility.HammingDistance(h, 0); if (bits < 10 || bits > 22) // 5 27 (10 22) { // try further in the fingerprint continue; } } int[] data = new int[1] { index }; if (subFingerLookup.ContainsKey(h)) { subFingerLookup[h] = CombineArrays(subFingerLookup[h], data); } else { subFingerLookup.Add(h, data); } } //foreach return(subFingerLookup); }
public FingerprintSignature(object reference, long titelnummerTrackID, byte[] signature, long durationInMS, bool createLookupIndex = false) { SimilarityUtility.InitSimilarityUtility(); this.titelnummerTrackID = titelnummerTrackID; this.reference = reference; if (this.signature != null) { Signature = signature; } this.durationInMS = durationInMS; if (createLookupIndex) { dSubFingerLookup = CreateLookupDictionary(); } }
/// <summary> /// Calculate the BER between 2 fingerprints /// </summary> public static int BER(FingerprintSignature f1, FingerprintSignature f2) { if (f1.SubFingerprintCount != f2.SubFingerprintCount) { return(-1); } // length of both needs to be equal! int BER = 0; // Bit Error Rate for (int i = 0; i < f1.SubFingerprintCount; i++) { int bits = SimilarityUtility.HammingDistance(f1.SubFingerprint(i), f2.SubFingerprint(i)); if (bits > 0) { BER += bits; } } // for i return(BER); }