You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言下SDT写入ts文件时CRC-32校验值计算问题

解决SDT包CRC-32校验值计算问题(Go语言)

核心规则明确

SDT属于MPEG-TS的PSI/SI section,其末尾的4字节CRC-32必须遵循MPEG-2 CRC标准计算,且仅针对section的特定范围:

  • 计算范围:从section header的section_length字段之后的第一个字节,到CRC字段之前的最后一个字节(即排除section header前3字节,以及最后4字节的CRC本身)。
  • CRC参数:多项式0x04C11DB7,初始值0xFFFFFFFF,最终结果需反转比特后异或0xFFFFFFFF。

Go语言实现代码

直接基于标准库hash/crc32实现符合要求的计算逻辑:

package main

import (
    "hash/crc32"
)

// 预生成MPEG-2 CRC-32的计算表(多项式与IEEE相同,但处理逻辑不同)
var mpeg2CRCTable = crc32.MakeTable(crc32.IEEE)

// CalculateSDTCRC 计算SDT section的CRC-32校验值
// sectionBytes: 完整的SDT section字节流(已剥离TS头)
func CalculateSDTCRC(sectionBytes []byte) uint32 {
    // 确定CRC计算的有效数据范围:跳过前3字节的section header,排除最后4字节的CRC字段
    if len(sectionBytes) <= 7 {
        return 0 // 数据长度不足,无效
    }
    dataToCheck := sectionBytes[3 : len(sectionBytes)-4]

    // 初始值为0xFFFFFFFF,更新计算CRC
    crc := crc32.Update(0xFFFFFFFF, mpeg2CRCTable, dataToCheck)
    // 反转比特并异或0xFFFFFFFF得到最终结果
    crc = ^crc32.ReverseBits(crc)
    return crc
}

常见错误排查

  • 错误计算范围:不要把TS包的4字节同步头包含进来,必须先剥离TS头,只处理SDT的section payload;也不要把CRC字段本身加入计算。
  • CRC规则误用:不要直接使用crc32.ChecksumIEEE,它的初始值是0,输出也没有反转异或,不符合MPEG-2标准。
  • 字节顺序混淆:计算时保持原始字节流顺序,无需反转字节,仅在最后处理CRC结果的比特顺序。

内容的提问来源于stack exchange,提问作者Kseniya Chapygova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:52:48