-
Notifications
You must be signed in to change notification settings - Fork 0
/
hat-convert.py
66 lines (54 loc) · 2.05 KB
/
hat-convert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import base64
import os
import sys
# pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
"""
This Python 3 script will decrypt your .hat files and output a .png and
.txt file with the corresponding metadata that was stored in the .hat
"""
# put file name here
input_filename = "BigHeadWhite.hat"
output_filename_base = os.path.splitext(input_filename)[0]
# https://github.com/penguinscode/Quackhead/blob/master/quackhead.js#L14
key_encoded = "8xaYIAH0em9hKg0CEw8t5g=="
key = base64.b64decode(key_encoded)
if not os.path.isfile(input_filename):
print(input_filename, "file was not found, please change the filename in the Python file")
sys.exit()
def decryptHat(hat):
iv_len = int.from_bytes(hat[:4], byteorder='little')
iv = bytes(hat[4:4+iv_len])
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
hat_stream = hat[20:]
plaintext = cipher.decrypt(hat_stream)
return plaintext
def parseMetadata(hat):
magic_number = int.from_bytes(hat[0:8], byteorder='little')
hat_name_len = int.from_bytes(hat[8:9], byteorder='little')
hat_name = hat[9:9+hat_name_len].decode()
offset = 9+hat_name_len
offset_end = offset+4
image_size = int.from_bytes(hat[offset:offset_end], byteorder='little')
metadata = "magic: {}\nname: {}\nsize: {}".format(magic_number, hat_name, image_size)
return metadata, offset_end
with open(input_filename, "rb") as hatfile:
hat = hatfile.read()
decrypted = decryptHat(hat)
metadata, png_offset = parseMetadata(decrypted)
print(metadata)
filename_metadata = "{}.txt".format(output_filename_base)
filename_image = "{}.png".format(output_filename_base)
if os.path.isfile(filename_metadata):
print(filename_metadata, "already exists, not overwriting")
else:
with open(filename_metadata, "w") as out_metafile:
out_metafile.write(str(metadata))
print(filename_metadata, "saved")
if os.path.isfile(filename_image):
print(filename_image, "already exists, not overwriting")
else:
with open(filename_image, "wb") as out_hatfile:
out_hatfile.write(decrypted[png_offset:])
print(filename_image, "saved")