[Console]::OutputEncoding = [Text.Encoding]::UTF8 $ErrorActionPreference = "Stop" function H2B($hex) { if (-not $hex) { return $null } $n = $hex.Length / 2 $b = New-Object byte[] $n for ($i = 0; $i -lt $n; $i++) { $b[$i] = [Convert]::ToByte($hex.Substring(2*$i, 2), 16) } return $b } $lines = [IO.File]::ReadAllLines("$env:TEMP\opencode\ss123.tsv") $dmx = New-Object System.Collections.ArrayList foreach ($l in $lines) { $p = $l -split "`t"; if ($p.Count -lt 5 -or -not $p[4]) { continue } if ($p[1] -ne "192.168.123.113" -or $p[2] -ne "192.168.123.1") { continue } $b = H2B $p[4]; if ($b.Length -ne 1084) { continue } if ([int]$b[4] -ne 4) { continue } if (-not ($b[0x20] -eq 1 -and $b[0x21] -eq 1)) { continue } [void]$dmx.Add(@{ t=[double]$p[0]; b=$b }) } Write-Host ("DMX-A 帧数: {0}" -f $dmx.Count) if ($dmx.Count -eq 0) { exit } # --- 1. 头部逐字节变化分析 (0x00-0x3B): 常量 or 变量 --- Write-Host "`n=== 头部 0x00-0x3B 逐字节分析 ===" $first = $dmx[0].b for ($off = 0; $off -lt 0x3C; $off++) { $min = 255; $max = 0; $diff = 0 foreach ($f in $dmx) { $v = [int]$f.b[$off]; if ($v -lt $min) { $min = $v }; if ($v -gt $max) { $max = $v }; if ($v -ne [int]$first[$off]) { $diff++ } } if ($diff -gt 0) { Write-Host (" 0x{0:x2}: 变量 首值={1:x2} min={2:x2} max={3:x2} 变化帧数={4}" -f $off, $first[$off], $min, $max, $diff) } } Write-Host " (未列出 = 全部帧常量)" Write-Host "`n=== 常量头 hex (首帧 0x00-0x3B) ===" Write-Host (" " + (($first[0..0x3B] | ForEach-Object { $_.ToString("x2") }) -join " ")) # --- 2. 变化字段的语义: 找 16/32 位递增计数器 --- Write-Host "`n=== 疑似序号字段 (按 LE u16/u32 检验单调性) ===" foreach ($off in @(0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A)) { $vals = $dmx | ForEach-Object { [int]$_.b[$off] + [int]$_.b[$off+1]*256 } $inc = 0; $dec = 0 for ($i = 1; $i -lt $vals.Count; $i++) { if ($vals[$i] -gt $vals[$i-1]) { $inc++ } elseif ($vals[$i] -lt $vals[$i-1]) { $dec++ } } if ($inc -gt $vals.Count * 0.8 -or $dec -gt $vals.Count * 0.8) { Write-Host (" u16@0x{0:x2}: 首={1} 尾={2} 增={3} 减={4}" -f $off, $vals[0], $vals[-1], $inc, $dec) } } # --- 3. 通道数据区 0x3C-0x43B (1024B): 非零分布 --- Write-Host "`n=== 通道数据区非零统计 (0x3C 起 1024B) ===" $nz = @{} foreach ($f in $dmx) { for ($i = 0x3C; $i -lt 0x43C; $i++) { if ($f.b[$i] -ne 0) { $rel = $i - 0x3C; if (-not $nz.ContainsKey($rel)) { $nz[$rel] = 0 }; $nz[$rel]++ } } } $nzKeys = $nz.Keys | Sort-Object Write-Host (" 非零字节位置数: {0}" -f $nzKeys.Count) if ($nzKeys.Count -gt 0) { Write-Host (" 最小相对偏移: {0} (CH{1}) 最大相对偏移: {2} (CH{3})" -f $nzKeys[0], ($nzKeys[0]+1), $nzKeys[-1], ($nzKeys[-1]+1)) $ranges = @(); $rs = $nzKeys[0]; $rp = $nzKeys[0] foreach ($k in $nzKeys) { if ($k -gt $rp + 1) { $ranges += "$rs-$rp"; $rs = $k }; $rp = $k } $ranges += "$rs-$rp" Write-Host (" 连续非零区间 (相对0x3C): " + ($ranges -join ", ")) } # 首帧前 32 通道值 Write-Host (" 首帧 CH1-32: " + (($first[0x3C..0x5B] | ForEach-Object { $_.ToString("x2") }) -join " ")) # --- 4. 速率与时间隔 --- $tg = New-Object System.Collections.ArrayList for ($i = 1; $i -lt $dmx.Count; $i++) { [void]$tg.Add([int](($dmx[$i].t - $dmx[$i-1].t) * 1000)) } $tgs = $tg | Sort-Object Write-Host ("`n=== 帧间隔ms: min={0} p50={1} p90={2} max={3} 率={4:N1}/s ===" -f $tgs[0], $tgs[[int]($tgs.Count/2)], $tgs[[int]($tgs.Count*0.9)], $tgs[-1], ($dmx.Count / ($dmx[-1].t - $dmx[0].t)))