#!/usr/bin/env python3
"""
Extract MIFARE card responses from MISO around the username location
"""
import csv

print("[*] Reading export.csv and extracting MISO bytes...")

with open('export.csv', 'r') as f:
    reader = list(csv.DictReader(f))

# Extract MISO bytes from region around line 68247 (where we found data)
# But this time get a much larger range
start_line = 67000  
end_line = 69000

miso_bytes = []
for i in range(start_line, min(end_line, len(reader))):
    row = reader[i]
    if row['type'] == 'result' and row['miso'] and row['miso'].startswith('0x'):
        miso_byte = int(row['miso'], 16)
        miso_bytes.append(miso_byte)

print(f"[+] Extracted {len(miso_bytes)} MISO bytes from lines {start_line}-{end_line}")

# Show miso bytes
print("\n[*] MISO bytes (card responses):")
for i in range(0, min(512, len(miso_bytes)), 16):
    chunk = miso_bytes[i:i+16]
    hex_str = ' '.join(f'{b:02x}' for b in chunk)
    ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
    print(f"  {i:04x}: {hex_str:<48} {ascii_str}")

# Search for 'axel_outrun' or 'teptast'
axel = [0x61, 0x78, 0x65, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x72, 0x75, 0x6e]  # 'axel_outrun'
tept = [0x74, 0x65, 0x70, 0x74, 0x61, 0x73, 0x74]  # 'teptast'

found = False
for i in range(len(miso_bytes) - 10):
    if miso_bytes[i:i+11] == axel or miso_bytes[i:i+7] == tept:
        print(f"\n[+++] FOUND username at MISO offset {i}!")
        
        # Show context
        start = max(0, i - 16)
        end = min(len(miso_bytes), i + 80)
        
        print(f"\n[*] Context (showing 16 before, 80 after):")
        for j in range(start, end, 16):
            chunk = miso_bytes[j:j+16]
            hex_str = ' '.join(f'{b:02x}' for b in chunk)
            ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
            marker = ' <<<' if j <= i < j + 16 else ''
            print(f"  {j:04x}: {hex_str:<48} {ascii_str}{marker}")
        
        # Extract 16-byte blocks
        block_start = (i // 16) * 16
        
        print(f"\n{'='*70}")
        for block_num in range(0, 4):
            offset = block_start + (block_num * 16)
            if offset + 16 <= len(miso_bytes):
                block = miso_bytes[offset:offset+16]
                hex_str = ''.join(f'{b:02x}' for b in block)
                ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in block)
                
                print(f"\nBlock {block_num} (offset {offset:04x}):")
                print(f"  HEX:   {hex_str}")
                print(f"  ASCII: '{ascii_str}'")
                
                if block_num == 0:
                    print(f"  >>> SECTOR 8 (Username)")
                elif block_num == 1:
                    print(f"  >>> SECTOR 22 (Authorization Code) <<<")
                elif block_num == 2:
                    print(f"  >>> SECTOR 34 (Access Level) <<<")
        
        print(f"{'='*70}")
        found = True
        break

if not found:
    print("\n[-] Username not found in MISO")
    print("[*] Trying to filter out status bytes (0x00, 0x92, 0x10, 0x1A, 0x8C, 0x94, 0x98)...")
    
    # Common MFRC522 status bytes
    status_bytes = [0x00, 0x92, 0x10, 0x1A, 0x8C, 0x94, 0x98, 0x88]
    filtered = [b for b in miso_bytes if b not in status_bytes]
    
    print(f"[+] After filtering: {len(filtered)} bytes")
    print("\n[*] First 256 filtered bytes:")
    for i in range(0, min(256, len(filtered)), 16):
        chunk = filtered[i:i+16]
        hex_str = ' '.join(f'{b:02x}' for b in chunk)
        ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)
        print(f"  {i:04x}: {hex_str:<48} {ascii_str}")
