SHARE
TWEET

Untitled

a guest Aug 25th, 2019 87 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import sys
  2. import os
  3.  
  4. class Data(object):
  5.     @staticmethod
  6.     def hex(data):
  7.         return " ".join("%02X" % (ord(c)) for c in data)
  8.  
  9. class Rom(object):
  10.     HEADER_SIZE = 0x200
  11.  
  12.     class Error(Exception):
  13.         pass
  14.  
  15.     class Block(object):
  16.         __slots__ = ("start", "end")
  17.  
  18.         def __init__(self, start, end):
  19.             self.start = start
  20.             self.end   = end
  21.  
  22.         @property
  23.         def size(self):
  24.             return self.end - self.start
  25.  
  26.     __slots__ = ("_file", "_header", "data")
  27.  
  28.     def __init__(self, file):
  29.         self._file = file
  30.  
  31.         self.__check()
  32.  
  33.         with open(file, "rb") as rom:
  34.             if self._header:
  35.                 rom.seek(Rom.HEADER_SIZE)
  36.  
  37.             self.data = rom.read()
  38.  
  39.     def __check(self):
  40.         name = self._file.lower()
  41.  
  42.         if name.endswith(".sfc"):
  43.             self._header = False
  44.         elif name.endswith(".smc"):
  45.             self._header = True
  46.         else:
  47.             raise Rom.Error("Invalid ROM: %s" % (self._file))
  48.  
  49.     def compare(self, rom):
  50.         start = None
  51.  
  52.         for i in xrange(len(self.data)):
  53.             try:
  54.                 if self.data[i] == rom.data[i]:
  55.                     if start is not None:
  56.                         yield Rom.Block(start, i)
  57.  
  58.                         start = None
  59.                 else:
  60.                     if start is None:
  61.                         start = i
  62.             except IndexError:
  63.                 break
  64.  
  65.         if start is not None:
  66.             yield Rom.Block(start, i)
  67.  
  68. def main(argc, argv):
  69.     if argc != 3:
  70.         sys.exit(1)
  71.  
  72.     rom1 = Rom(argv[1].strip())
  73.     rom2 = Rom(argv[2].strip())
  74.  
  75.     total = 0
  76.     size  = 0
  77.  
  78.     biggest  = 0
  79.     smallest = os.path.getsize(argv[1].strip())
  80.  
  81.     os.system("cls")
  82.  
  83.     for block in rom1.compare(rom2):
  84.         total += 1
  85.         size  += block.size
  86.  
  87.         biggest  = max(biggest, block.size)
  88.         smallest = min(smallest, block.size)
  89.  
  90.         start = block.start
  91.         end   = min(start+8, block.end)
  92.         data1 = rom1.data[start:end]
  93.         data2 = rom2.data[start:end]
  94.  
  95.         print("[BLOCK] 0x%06X -> 0x%06X | %s -> %s" % (
  96.             block.start, block.end,
  97.             Data.hex(data1), Data.hex(data2)
  98.         ))
  99.  
  100.     if total > 0:
  101.         print("")
  102.         print("------------------------------")
  103.         print("[TOTAL] %i block(s)" % (total))
  104.         print("[SIZE]  %i byte(s)" % (size))
  105.         print("------------------------------")
  106.  
  107.         if total > 1:
  108.             print("")
  109.             print("------------------------------")
  110.             print("[BIGGEST]  %i byte(s)" % (biggest))
  111.             print("[SMALLEST] %i byte(s)" % (smallest))
  112.             print("------------------------------")
  113.     else:
  114.         print("[*] ROMs match!")
  115.  
  116.     print("")
  117.  
  118.     os.system("pause")
  119.  
  120.     sys.exit(0)
  121.  
  122. if __name__ == "__main__":
  123.     main(len(sys.argv), sys.argv)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top