Skip to content

Instantly share code, notes, and snippets.

@bbayles
Created November 7, 2024 03:06
Show Gist options
  • Save bbayles/7ad628eca2ce8a709440c10fe82edd89 to your computer and use it in GitHub Desktop.
Save bbayles/7ad628eca2ce8a709440c10fe82edd89 to your computer and use it in GitHub Desktop.
Generate special initials for Ecco the Dolphin: Defender of the Future
from itertools import product
from string import ascii_uppercase
from struct import unpack
base_name_buffer = b'\x00\xd4\x46\x51\x41\x72\x10\xd7\xd3\x20\xaa\xed\xb5\xde\x14\x93\xe7\xac\x4e\xc9\x69\x8a\x58\x8f\x3b\x78\x32\xe5\x5d\x76\xdc\xcb'
encryption_data = b'\x5e\xdc\xcd\xe5\xc8\xec\xca\x92\x72\xbd\xc3\x0b\xe4\x8d\xc4\x7c\x47\x18\xa0\xe2\xd1\x28\xa7\x95\x6b\x79\xae\x0c\xfd\x49\xa9\x7b\x6c\x54\x16\xeb\xfa\x64\x11\x9c\x40\x35\x18\x05\xd6\x05\x1f\x72\x75\x90\x7b\xec\xe3\xa0\x7c\x9b\x59\xf1\x75\x02\xcf\xc1\x72\x75\x3a\xcc\x7a\xf8\xac\xfc\x7d\x8f\x16\xad\x74\x16\x80\x9d\x73\x61\x23\x08\x17\xff\xb5\x38\x10\x88\x0f\x69\x19\x11\x99\x59\x1e\x66\x08\x44\xa1\xf6\x9e\x74\xa6\x81\x24\x25\xaf\x18\xb2\x15\xa8\x6f\x11\x80\xcc\xf1\x87\xb0\xcb\x86\x3d\xe1\xc2\x1f\xab\xd1\xc5\x68\x96\xfc\xa3\xde\x00\xcc\xa4\xa9\xba\x9d\xad\x30\x2c\xad\xaa\x47\x8f\x38\xce\xd9\x19\x08\xc9\xae\xa3\x59\xc0\x37\x35\x69\xc7\x40\xa4\x74\x78\xd0\x32\x44\x7f\xa7\x88\x15\x76\x3e\x1e\x25\x71\x49\xbd\xb0\x15\xd7\x2b\x80\x12\xa0\x91\xd1\x1b\x39\x07\xe1\x1c\x4e\xf2\xec\x14\xc3\x64\xdc\x13\xb4\xde\x8d\x1a\x2d\x48\xbd\x1d\x5a\xeb\x28\x79\xc4\x7d\x18\x7e\xb3\xc7\x49\x77\x2a\x51\x79\x70\x5d\xc0\x64\xcf\xcd\x56\x54\xc8\xba\xec\x05\xc1\x23\x7a\x35\xc6\x54\xd9\xa0\xa2\xca\x4f\x90\xa5\xbd\xf5\xc1\xac\x24\x63\xf1\xab\x53\xce\x9d\x11\x93\x58\xad\x16\xe4\xe2\xfc\x1f\x7d\x74\xcc\x18\x0a\xd7\x59\x7c\x94\x41\x69\x7b\xe3\xfb\x38\x72\x7a\x6d\x08\x75\x0d\xfc\x15\xca\x9d\x6a\x25\xcd\xea\xd0\x74\xc4\x73\x46\x44\xc3\x04\xe5\xd1\xa7\x9a\x73\xe1\xa0\xed\xc9\xb0\xa9\x74\x5f\x80\xae\x03\xaa\x8d\xa6\x8e\x3c\xbd\xa1\xf9\x86\xec\xa8\x60\x10\xdc\xaf\x17\xb3\x49\xcb\x89\x25\x79\xcc\xfe\x9f\x28\xc5\x67\x09\x18\xc2\x10\x98\x05\x7d\x80\x0e\x35\x7a\xf7\xb4\x64\x73\x6e\x22\x54\x74\x19\x81\xc1\x10\x87\x17\xf1\x17\xf0\xad\xa0\x1e\x69\x3b\x90\x19\x1e\x06\xbd\x7f\xa8\x90\x8d\x78\xdf\x2a\xdc\x71\x46\xbc\xec\x76\x31\x1f\x79\x12\xaf\x89\x49\x15\xd8\x33\x18\x1c\x41\xa5\x28\x1b\x36\x34\x35\xa4\xa6\xa2\x05\xa3\xd1\x18\x54\xaa\x48\x8e\x64\xad\x3f\x2d\xf1\xc9\xa1\xbb\xc1\xce\xd6\x01\x90\xc7\x4f\x97\xa0\xc0\x38\x62\xad\xc8\xb5\xf4\x9d\xcf\xc2\x4e\xcc\xc6\x5b\xd8\xfc\xc1\x2c\x7b\x69\xa5\xb2\xed\x59\xa2\xc5\x57\x08\xab\x5c\xc1\x38\xac\x2b\x50\x25\x13\xbb\xc6\x15\x14\xcc\x7c\x44\x1d\x55\xea\x74\x1a\x22\x49\xe1\x7e\xbc\xdf\xd1\x79\xcb\x65\x80\x70\x52\xf3\xb0\x77\x25\x7e\x5f\x75\x08\xe8\x6f\x72\x7f\x52\x3e\x7b\xe6\xc4\x0e\x7c\x91\x67\x9b\x18\x0f\xf1\xab\x1f\x78\x4b\xfa\x16\xe1\xdd\xca\x11\x96\x4c\xd7\xae\x06\xda\xe7\xa9\x71\x60\xb6\xa0\xe8\xf6\x86\xa7\x9f\x55\x13\xc3\x01\xc3\x23\xc4\x76\x79\x72\xcd\xef\xef\x42\xca\x98\x1a\x4f\xc2\x15\x8c\x7f\xc5\x62\x36\x2e\xcc\xfb\xa0\x1e\xcb\x8c\x03\x8b\xaf\x12\x95\xbb\xa8\x65\x2f\xea\xa1\xfc\xb9\xda\xa6\x8b\x28\xc7\x19\x1b\xbe\xf7\x1e\x6c\x04\xa6\x17\xf5\x92\x96\x10\x82\x31\x03\x74\x1c\xa7\x33\x73\x6b\x1d\x62\x7a\xf2\x8b\x52\x7d\x85\xb6\x7f\x1b\x33\x20\x4f\x1c\x44\x9a\x1e\x15\xdd\x0c\x2e\x12\xaa\xaf\xbb\x76\x34\x39\x8b\x71\x43\x83\xda\x78\xda\x15\xea\x7f\xad\x84\xf7\xc0\x3d\x12\xc7\xc7\x4a\xa8\x96\xce\xd3\x3e\xa6\xc9\xa4\x9d\x33\xad\x3a\x0b\x03\xaa\x4d\xb1\x52\xa3\xd4\x27\x62\xa4\xa3\xd2\x6f\xac\x2e\x44\x5f\xab\x59\xfe\x0e\xa2\xc0\x68\x3e\xa5\xb7\xcb\xab\xc1\x29\x5d\x9b\xc6\x5e\xe7\xca\xcf\xc7\x71\xfa\xc8\xb0\xe0\xe7\x77\x20\x76\xd7\x70\x57\xcc\x86\x79\xce\x5a\xb6\x7e\xb9\xf9\x23\x1a\x27\x6f\x13\x1d\x50\xd5\x42\x14\xc9\x43\x72\x13\xbe\xee\x1e\xa9\x7e\x78\x2e\xae\x09\xc2\x7f\xa7\x90\x54\x4f\xa0\xe7\xf7\xda\xc4\x79\x61\xea\xc3\x0e\xdb\xbb\xca\x97\x4d\x8b\xcd\xe0\xdc\x96\x72\x70\x4a\xa6\x75\x07\xf0\xf7\x7c\x9e\x66\xc7\x7b\xe9\xc5\x52\x1f\x77\x53\x62\x18\x00\xe9\x33\x11\x99\x7f\x03\x16\xee\x8a\x0e\x1e\x63\x1c\x3e\x19\x14\xa6\x6f\x10\x8d\x30\x5f\x17\xfa\x93\xca\x73\x64\x05\xfa\x74\x13\xbf\xab\x7d\x8a\x29\x9b\x7a\xfd\xb8\x86\xc5\x6d\x2e\xb6\xc2\x1a\x94\xe7\xcb\x83\x02\xd7\xcc\xf4\xa1\x42\xa8\x6a\x37\x72\xaf\x1d\x8d\x23\xa6\x84\x1b\x13\xa1\xf3\x26\x3e\xc7\x45\xb0\x0e\xc0\x32\x0a\x5f\xc9\xab\x9c\x6f\xce\xdc\x3f\xfa\xaa\x42\xa9\xca\xad\x35\x13\x9b\xa4\xac\x85\xab\xa3\xdb\x14\xb6\x1c\x4b\x82\x86\x1b\x3c\x38\xd7\x12\xa5\xae\xe7\x15\xd2\x0d\x72\x71\x4c\x9b\x42\x76\x3b\x21\x13\x7f\xa2\xb7\x23\x78\xd5\x42\x2e\x70\x58\xd4\x1e\x77\x2f\x6e\x4f\x7e\xb6\xf8\x7f\x79\xc1\x5b\xea\x1d\x5f\xcd\xda\x1a\x28\x77\x8b\x13\xb1\xe1\xbb\x14\xc6\x70\xa6\xab\x56\xe6\x96\xac\x21\x5c\xc7\xa5\xb8\xca\xf7\xa2\xcf\x69\x62\xc6\x51\xff\x52\xc1\x26\x45\x03\xc8\xbf\xd3\x33\xcf\xc8'
encrypted_ints = unpack('<256I', encryption_data)
key_bytes = bytes.fromhex('5edccde5')
key_int = unpack('<I', key_bytes)[0]
decrypted_ints = [x ^ key_int for x in encrypted_ints]
target_data = b'\x27\xd6\x88\x93\x3b\xc2\x47\x5b\x8d\xf6\x1e\x2d\xae\x96\xd9\x6e\xea\x7c\x36\x89\xbb\xed\x78\x4a'
target_ints = {x:i for i, x in enumerate(unpack('<6I', target_data))}
for size in range(1, 8 + 1):
name_buffer = bytearray(base_name_buffer)
for name in product(ascii_uppercase.encode(), repeat=size):
name_buffer[0:size] = name
name_buffer[size] = 0
checksum = 0xffffffff
for i in range(0x20):
d = name_buffer[i]
checksum = decrypted_ints[(checksum ^ d) & 0xff] ^ checksum >> 8
index = target_ints.get(checksum)
if index is not None:
print(bytes(name).decode(), format(checksum, '08x'), index, sep='\t')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment