63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
import sys
|
|
import re
|
|
|
|
|
|
class Scorpion:
|
|
def __init__(self, args):
|
|
self.args = self.args_init(args[1:])
|
|
self.signatures = {
|
|
"jpg": [b"\xFF\xD8\xFF"],
|
|
"png": [b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"],
|
|
"gif": [b"GIF87a",b"GIF89a"],
|
|
"bmp": [b"BM"]
|
|
}
|
|
self.png_cluster = {
|
|
"IHDR": {"Width": 4, "Height": 4, "Bit Depth": 1, "Color Type": 1, "Compression": 1, "Filter": 1, "Interlace": 1}
|
|
}
|
|
def args_init(self, args: list[str]) -> set[str]:
|
|
argset = set()
|
|
pattern = re.compile(r'^.*\.(?:jpe?g|png|gif|bmp)$', re.IGNORECASE)
|
|
for arg in args:
|
|
print(arg)
|
|
if not pattern.match(arg):
|
|
print("Error : Invalid file")
|
|
return
|
|
argset.add(arg)
|
|
return argset
|
|
|
|
def hexdump(self, data: bytes, width: int = 16):
|
|
for i in range(0, len(data), width):
|
|
chunk = data[i:i+width]
|
|
hex_bytes = " ".join(f"{b:02X}" for b in chunk)
|
|
ascii_part = "".join(chr(b) if 32 <= b < 127 else "." for b in chunk)
|
|
print(f"{i:08X} {hex_bytes:<{width*3}} {ascii_part}")
|
|
|
|
def get_file_type(self, data: bytes):
|
|
for filetype, sigs in self.signatures.items():
|
|
if any(data.startswith(sig) for sig in sigs):
|
|
return filetype
|
|
return None
|
|
|
|
def run(self):
|
|
for arg in self.args:
|
|
with open(arg, "rb") as f:
|
|
data = f.read()
|
|
filetype = self.get_file_type(data)
|
|
self.hexdump(data)
|
|
match filetype:
|
|
case "jpg":
|
|
return None
|
|
case "png":
|
|
self.read_png(data)
|
|
case "gif":
|
|
return None
|
|
case "bmp":
|
|
return None
|
|
case _:
|
|
return None
|
|
def read_png(self, data):
|
|
for cluster, cluster_values in self.png_cluster.values():
|
|
|
|
if __name__ == "__main__":
|
|
scorpion = Scorpion(sys.argv)
|
|
scorpion.run() |