#!/usr/bin/env python3
"""
Smarter RFID data extraction from logic capture
Look for recognizable patterns in the raw data
"""

import struct

def hex_dump(data, max_bytes=256):
    """Print hex dump of data"""
    for i in range(0, min(len(data), max_bytes), 16):
        chunk = data[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:08x}  {hex_str:<48}  {ascii_str}')

def search_for_patterns(data):
    """Search for recognizable RFID patterns"""
    print("\n[*] Searching for patterns...")
    
    # Look for UID-like patterns (4 bytes that look like a UID)
    # UIDs often start with manufacturer bytes like 0x04, 0x08, etc.
    potential_uids = []
    for i in range(len(data) - 4):
        if data[i] in [0x04, 0x08, 0x09, 0x44, 0x62]:  # Common MIFARE manufacturer IDs
            uid = data[i:i+4]
            uid_hex = ''.join(f'{b:02x}' for b in uid)
            potential_uids.append((i, uid_hex))
    
    print(f"\n[+] Found {len(potential_uids)} potential UIDs:")
    for offset, uid in potential_uids[:10]:
        print(f"    Offset {offset:08x}: {uid}")
    
    # Look for 16-byte blocks (MIFARE Classic blocks)
    print("\n[*] Looking for 16-byte data blocks...")
    for i in range(0, min(512, len(data) - 16), 16):
        block = data[i:i+16]
        # Check if it's not all zeros or all FFs
        if not all(b == 0 for b in block) and not all(b == 0xff for b in block):
            # Check if it has some structure (not random)
            unique_count = len(set(block))
            if 3 <= unique_count <= 12:  # Some variation but not completely random
                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"    {i:04x}: {hex_str}  [{ascii_str}]")

def look_for_strings(data):
    """Look for ASCII strings (names, etc.)"""
    print("\n[*] Searching for ASCII strings...")
    strings = []
    current = []
    
    for b in data:
        if 32 <= b < 127:  # Printable ASCII
            current.append(chr(b))
        else:
            if len(current) >= 4:
                strings.append(''.join(current))
            current = []
    
    if len(current) >= 4:
        strings.append(''.join(current))
    
    print(f"[+] Found {len(strings)} strings:")
    for s in strings[:20]:
        print(f"    '{s}'")

def analyze_channel(filename):
    """Analyze a single channel file"""
    print(f"\n{'='*60}")
    print(f"Analyzing: {filename}")
    print('='*60)
    
    with open(filename, 'rb') as f:
        data = f.read()
    
    print(f"[+] File size: {len(data)} bytes")
    
    # Show hex dump
    print("\n[*] Hex dump (first 256 bytes):")
    hex_dump(data)
    
    # Search for patterns
    search_for_patterns(data)
    
    # Look for strings
    look_for_strings(data)

if __name__ == "__main__":
    # Analyze each channel
    for i in range(4):
        analyze_channel(f"extracted/digital-{i}.bin")
