#!/usr/bin/env python # # bitdiff -- Determine differing bits in hexadecimal hash values # # From: Rick van Rein import sys print "This program demonstrates the sensitivity of hash values in hex representation" print "The expectation value of changing bits between different inputs is always 50.0%%" def countbits (nr): if nr < 0: raise 'Counting bits of negative numbers is undefined' bits = 0 while nr > 0: if nr & 0x01: bits = bits + 1 nr = nr >> 1 return bits def hex2long (strval): numval = 0L for ch in strval: numval = numval << 4 if ch in '0123456789': numval = numval + ord (ch) - ord ('0') elif ch in 'abcdef': numval = numval + ord (ch) - ord ('a') + 10 elif ch in 'ABCDEF': numval = numval + ord (ch) - ord ('A') + 10 else: raise ("Naughty character '%c' found in hexstring" % ch) return numval sys.stdout.write ('Hash value #1: '); h1 = sys.stdin.readline () if h1 [-1] == '\n': h1 = h1 [:-1] sys.stdout.write ('Hash value #2: '); h2 = sys.stdin.readline () if h2 [-1] == '\n': h2 = h2 [:-1] if len (h1) != len (h2): raise "Hash lengths differ -- cannot continue" if len (h1) == 0: raise "Hashes are empty -- not very convincing, ej?" numbits = 4*len (h1) hash1 = hex2long (h1) hash2 = hex2long (h2) diffbits = countbits (hash1 ^ hash2) perc = (100.0 * diffbits) / (1.0 * numbits) print "%d out of %d bits different, or %3.1f%%\n" % (diffbits, numbits, perc)