import traceback, sys, os if __name__ == "__main__": ts = time.time() def read_file(path, max_sectors = 10000): sum_bits64 = [0] * 64 sum_bits32 = [0] * 32 sum_bits16 = [0] * 16 sum_bits8 = [0] * 8 sum_bits4 = [0] * 4 ctr = 0 try: with open(path, "rb") as f: while True: sector = f.read(512) # Skip empty sectors if sector == b"\x00" * 512: continue # End when there is no more data if sector == b"" or sector == None: break ctr += 1 # Read sector and sum up bits for i in range(0, 512, 8): byte = sector[i:(i+8)] try: bits = [0] * 64 for j in range(8): for k in range(8): pos = j * 8 + k bits[pos] = ((byte[j] >> k) & 1) except IndexError: break sum_bits64 = [x + y for x, y in zip(sum_bits64, bits)] sum_bits32 = [x + y for x, y in zip(sum_bits64[0:32], sum_bits64[32:])] sum_bits16 = [x + y for x, y in zip(sum_bits32[0:16], sum_bits32[16:])] sum_bits8 = [x + y for x, y in zip(sum_bits16[0:8], sum_bits16[8:])] sum_bits4 = [x + y for x, y in zip(sum_bits8[0:4], sum_bits8[4:])] # Output progress message if not ctr % 10: print(f"Reading sector no. {ctr} of {max_sectors}", end = "\r") sys.stdout.flush() # End if max. number of sectors are tested if ctr >= max_sectors: break except FileNotFoundError: print(f"FILE {path} NOT FOUND!") return 1 except PermissionError: print(f"CAN'T ACCESS FILE {path}!") return 2 # Print report print(f"\n\nREPORT FOR '{path}':") print("Counting bits which are 1\n") line = "" print("BIT | % | % | % | % | % ") print("-----------------------------------") for i in range(64): res = i if i < 4: line = f"{i:3} | " line += f"{int((sum_bits64[i] * 100) // ((ctr*512)/8)):2}% | " line += f"{int((sum_bits32[i] * 100) // ((ctr*512)/4)):2}% | " line += f"{int((sum_bits16[i] * 100) // ((ctr*512)/2)):2}% | " line += f"{int((sum_bits8[i] * 100) // ((ctr*512))):2}% | " line += f"{int((sum_bits4[i] * 100) // ((ctr*512)*2)):2}% |" elif i < 8: line = f"{i:3} | " line += f"{int((sum_bits64[i] * 100) // ((ctr*512)/8)):2}% | " line += f"{int((sum_bits32[i] * 100) // ((ctr*512)/4)):2}% | " line += f"{int((sum_bits16[i] * 100) // ((ctr*512)/2)):2}% | " line += f"{int((sum_bits8[i] * 100) // ((ctr*512))):2}% | " elif i < 16: line = f"{i:3} | " line += f"{int((sum_bits64[i] * 100) // ((ctr*512)/8)):2}% | " line += f"{int((sum_bits32[i] * 100) // ((ctr*512)/4)):2}% | " line += f"{int((sum_bits16[i] * 100) // ((ctr*512)/2)):2}% | " elif i < 32: line = f"{i:3} | " line += f"{int((sum_bits64[i] * 100) // ((ctr*512)/8)):2}% | " line += f"{int((sum_bits32[i] * 100) // ((ctr*512)/4)):2}% | " else: line = f"{i:3} | " line += f"{int((sum_bits64[i] * 100) // ((ctr*512)/8)):2}% | " print(line) def usage(): print("\nUSAGE:\n------") print(f"{os.path.basename(sys.argv[0])} /path/to/file.dd [no. of sectors to test]\n") print(f"e.g.: \n{os.path.basename(sys.argv[0])} C:/Users/DISKDOCTOR/Desktop/file.dd 10000\n") a = b[4] quit() # Check arguments if "-h" in sys.argv or "--help" in sys.argv or len(sys.argv) < 2 or len(sys.argv) > 3: usage() try: read_file(sys.argv[1], int(sys.argv[2])) except IndexError: read_file(sys.argv[1]) except TypeError: usage()