"""完整 dump TSA token 的所有 SEQUENCE 结构"""
import base64
import sys
import struct

p = r'C:\Users\13794\Desktop\workspace\工作\2026\aigcdemo\images\aigc1.jpg'
with open(p, 'rb') as f:
    data = f.read()

# 找 0xfe59 base64
exif_marker = data.find(b'Exif\x00\x00')
tiff_start = exif_marker + 6
bo = 'LE' if data[tiff_start:tiff_start+2] == b'II' else 'BE'
def r16(o): return data[o] | (data[o+1] << 8) if bo == 'LE' else (data[o] << 8) | data[o+1]
def r32(o): return data[o] | (data[o+1] << 8) | (data[o+2] << 16) | (data[o+3] << 24) if bo == 'LE' else (data[o] << 24) | (data[o+1] << 16) | (data[o+2] << 8) | data[o+3]

ifd0_off = r32(tiff_start + 4)
ifd0_n = r16(tiff_start + ifd0_off)
exif_off = None
for i in range(ifd0_n):
    eo = tiff_start + ifd0_off + 2 + i * 12
    if r16(eo) == 0x8769:
        exif_off = r32(eo + 8)
exif_n = r16(tiff_start + exif_off)
for i in range(exif_n):
    eo = tiff_start + exif_off + 2 + i * 12
    if r16(eo) == 0xfe59:
        count = r32(eo + 4)
        data_off = tiff_start + r32(eo + 8)
        b64 = data[data_off:data_off + count].rstrip(b'\x00').decode('ascii')
        break

tsa_bytes = base64.b64decode(b64)
print(f'TSA DER size: {len(tsa_bytes)}')

# 把 DER 字节 dump，看结构
# 用一个简单的 ASN.1 dump 工具
def parse_der(buf, indent=0, max_depth=5):
    if indent > max_depth:
        return []
    out = []
    p = 0
    while p < len(buf):
        if p >= len(buf):
            break
        tag = buf[p]
        cls = (tag & 0xc0) >> 6
        constructed = (tag & 0x20) != 0
        tag_num = tag & 0x1f
        p += 1
        if p >= len(buf):
            break
        L = buf[p]
        p += 1
        if L & 0x80:
            n = L & 0x7f
            if p + n > len(buf):
                break
            L = int.from_bytes(buf[p:p+n], 'big')
            p += n
        start = p
        end = start + L
        cls_name = ['UNIVERSAL', 'APPLICATION', 'CONTEXT', 'PRIVATE'][cls]
        tag_names = {1: 'BOOLEAN', 2: 'INTEGER', 3: 'BIT STRING', 4: 'OCTET STRING',
                     5: 'NULL', 6: 'OBJECT IDENTIFIER', 16: 'SEQUENCE', 17: 'SET',
                     0x18: 'GeneralizedTime'}
        tag_name = tag_names.get(tag_num, f'Tag {tag_num}')
        prefix = '  ' * indent
        if constructed and L < 1000:
            # dump 子节点
            if tag_num in (4,) and not (cls == 2 and L < 100):  # OCTET STRING 内容
                val = buf[start:end]
                if len(val) < 50:
                    out.append(f'{prefix}{cls_name} {tag_name} len={L}: {val.hex()}')
                else:
                    out.append(f'{prefix}{cls_name} {tag_name} len={L}: ({len(val)} bytes)')
            else:
                out.append(f'{prefix}{cls_name} {tag_name} len={L}:')
                if L > 0:
                    sub = parse_der(buf[start:end], indent + 1, max_depth)
                    out.extend(sub)
        else:
            val = buf[start:end]
            if tag_num == 6:  # OID
                # decode
                if len(val) >= 1:
                    out_arr = [val[0] // 40, val[0] % 40]
                    v = 0
                    for b in val[1:]:
                        v = (v << 7) | (b & 0x7f)
                        if not (b & 0x80):
                            out_arr.append(v)
                            v = 0
                    out.append(f'{prefix}{cls_name} {tag_name}: {".".join(str(x) for x in out_arr)}')
                else:
                    out.append(f'{prefix}{cls_name} {tag_name}: (empty)')
            elif tag_num == 2:  # INTEGER
                v = int.from_bytes(val, 'big')
                out.append(f'{prefix}{cls_name} {tag_name}: {v} (0x{v:x})')
            elif tag_num == 0x18:  # GeneralizedTime
                out.append(f'{prefix}{cls_name} {tag_name}: {val.decode("ascii","replace")}')
            elif L < 50:
                out.append(f'{prefix}{cls_name} {tag_name} len={L}: {val.hex()}')
            else:
                out.append(f'{prefix}{cls_name} {tag_name} len={L}: ({L} bytes)')
        p = end
    return out

for line in parse_der(tsa_bytes, max_depth=6):
    print(line)