python3 -c "
import struct, crcmod

crc32c = crcmod.predefined.mkCrcFun('crc-32c')

with open('/dev/nbd0','rb') as f:
    f.seek(1024)
    sb = f.read(1024)

uuid      = sb[104:120]
csum_seed = struct.unpack_from('<I', sb, 408)[0]
print(f'uuid:      {uuid.hex()}')
print(f'csum_seed: 0x{csum_seed:08x}')

# Read current group 0 GDT entry
data = bytearray(open('/tmp/merged_gdt.bin','rb').read())
e = bytearray(data[0:64])
print(f'Group 0 entry: {e.hex()}')
print(f'Current stored csum: 0x{struct.unpack_from(\"<H\",e,30)[0]:04x}')
print(f'e2fsck says should be: 0x03f5')

# Try different computation methods
# Method 1: standard
e2 = bytearray(e); struct.pack_into('<H',e2,30,0)
c1 = crc32c(uuid + struct.pack('<H',0) + bytes(e2), csum_seed) & 0xFFFF
print(f'Method 1 (seed+uuid+grp+entry): 0x{c1:04x}')

# Method 2: no seed
c2 = crc32c(uuid + struct.pack('<H',0) + bytes(e2)) & 0xFFFF
print(f'Method 2 (no seed):              0x{c2:04x}')

# Method 3: seed only on uuid
c3 = crc32c(struct.pack('<H',0) + bytes(e2), crc32c(uuid, csum_seed)) & 0xFFFF
print(f'Method 3 (seed on uuid first):   0x{c3:04x}')

# Method 4: what e2fsck uses internally
# From e2fsprogs source: crc32c(~0, uuid, 16) then crc32c(that, grp_le16+entry)
seed = crc32c(uuid, 0xFFFFFFFF)
c4 = crc32c(struct.pack('<H',0) + bytes(e2), seed) & 0xFFFF
print(f'Method 4 (e2fsprogs source):     0x{c4:04x}')

# Method 5: using stored seed from superblock offset 408
c5 = crc32c(struct.pack('<H',0) + bytes(e2), csum_seed) & 0xFFFF
print(f'Method 5 (stored seed only):     0x{c5:04x}')
"
