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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| def b2nle(b, n): return [int.from_bytes(b[i:i+n], byteorder='little', signed=False) for i in range(0, len(b), n)]
def ru16(data, offset): return data[offset] | (data[offset + 1] << 8)
def ru32(data, offset): return data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)
def wu16(data, offset, value): data[offset] = value & 0xFF data[offset + 1] = (value >> 8) & 0xFF
def wu32(data, offset, value): data[offset] = value & 0xFF data[offset + 1] = (value >> 8) & 0xFF data[offset + 2] = (value >> 16) & 0xFF data[offset + 3] = (value >> 24) & 0xFF
def sort_table(data, start, length): num_entries = length // 2 entries = [] for i in range(num_entries): offset = start + i * 2 even_index = data[offset] odd_index = data[offset + 1] entries.append((even_index, odd_index)) entries.sort(key=lambda x: (x[1], x[0])) for i, (even, odd) in enumerate(entries): offset = start + i * 2 data[offset] = even data[offset + 1] = odd
mem = bytearray(0x3000) inp = bytearray(b"aABBbbCCC999cccdddd5555DDDD00000EEEEEeeeee") for i in range(len(inp)): mem[i] = inp[i] tgt = bytearray.fromhex("B5030000E8C6660CD7C1C7649D111CBE127558CA6E004E4C452DA446898CD56535BB9BC2CBEB3630B5902AAA3544D1DCBAB805615AFDF96B6FCB5B7E5ADABEF4B60FEB170545B047F34A17F37111DA5A2B86EA79EB1AA2EC17A10B83796DD4F3DF965B57417F4EE768E98F4841770E1B9F1AAD3EF8A489D3635240B8AEC6") for i in range(len(tgt)): mem[i+0xE00] = tgt[i]
for i in range(0x200, 0x400, 2): mem[i] = (i - 0x200) // 2
for i in range(len(inp)): mem[0x201+2 * inp[i]] += 1 mem[0x201] = 1
mem[0x400:0x600] = mem[0x200:0x400] sort_table(mem, 0x200, 0x200) sort_table(mem, 0x400, 0x100)
active_nodes = [] base_addr = 0x1000 struct_size = 0x10 for i in range(0, 0x200, 2): chrord = mem[0x200 + i] freq = mem[0x201 + i] if freq > 0: addr = base_addr + struct_size * chrord active_nodes.append((freq, addr)) tree_ptr = 0x2000 while len(active_nodes) > 1: active_nodes.sort(key=lambda x: (x[0], x[1])) node1_freq, node1_addr = active_nodes.pop(0) node2_freq, node2_addr = active_nodes.pop(0) parent_freq = node1_freq + node2_freq parent_addr = tree_ptr mem[parent_addr + 0] = 0 wu16(mem, parent_addr + 1, parent_freq) wu32(mem, parent_addr + 8, node1_addr) wu32(mem, parent_addr + 12, node2_addr) wu32(mem, node1_addr + 4, parent_addr) wu32(mem, node2_addr + 4, parent_addr) active_nodes.append((parent_freq, parent_addr)) tree_ptr += struct_size if active_nodes: root_address = active_nodes[0][1] wu32(mem, 0xf00, root_address)
def write_bit(bit): offset = ru32(mem, 0x600) byte_idx = offset // 8 bit_idx = 7 - (offset % 8) addr = 0x604 + byte_idx if addr >= len(mem): mem.extend([0] * 0x100) if bit: mem[addr] |= (1 << bit_idx) else: mem[addr] &= ~(1 << bit_idx) wu32(mem, 0x600, offset + 1)
def func19(node_addr): left = ru32(mem, node_addr + 8) right = ru32(mem, node_addr + 12) if node_addr < 0x2000: write_bit(0) ch = (node_addr - 0x1000) >> 4 for i in range(8): bit = (ch >> i) & 1 write_bit(bit) else: write_bit(1) func19(left) func19(right) wu32(mem, 0x600, 0) for i in range(0x200): if 0x604 + i < len(mem): mem[0x604 + i] = 0 root_addr = ru32(mem, 0xF00)
func19(root_addr)
def func20(leaf_addr): parent = ru32(mem, leaf_addr + 4) if parent == 0: return left_child = ru32(mem, parent + 8) func20(parent) if leaf_addr == left_child: write_bit(0) else: write_bit(1)
def func21(): addr = 0 while mem[addr] != 0: ch = mem[addr] leaf_addr = 0x1000 + (ch << 4) func20(leaf_addr) addr += 1 func20(0x1000) func21()
final_bit_count = ru32(mem, 0x600) final_byte_count = (final_bit_count + 7) // 8
print(f"Output (hex): {mem[0x600:0x604 + final_byte_count].hex()}") print(f"Target (hex): {tgt.hex()}")
|