BAT表、链接描述符、文件内容与CRC32/MPEG-2校验

2023-10-11 11:30

本文主要是介绍BAT表、链接描述符、文件内容与CRC32/MPEG-2校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

BAT表、链接描述符、文件内容与CRC32/MPEG-2校验

0. 前言

这些笔记是几年前学习TS流解析和解复用的时候写的,现在整理出来记录一下。

当时的目标有如下两个:

  1. 解析接受到的TS流
  2. 从TS流中提取BAT表等数据,并解析具体内容。

1. TS包分析

需要解析TS流,先要解析接受到的每个TS包。

1.1 TS包结构

一个TS包由包头和包数据组成,总长度一般为188字节(也可能是204字节)。

包头一般为4字节左右,包含这个TS包的各种信息,剩余的是TS包数据。在数据中,可能会存在调整字节(非有效负载)。

1.2 TS包头和数据分析

TS包头由4字节组成,结构定义如下(C):

// Transport packet header
typedef struct TS_packet_header
{unsigned sync_byte                        : 8;unsigned transport_error_indicator        : 1;unsigned payload_unit_start_indicator    : 1;unsigned transport_priority                : 1;unsigned PID                            : 13;unsigned transport_scrambling_control    : 2;unsigned adaption_field_control            : 2;unsigned continuity_counter                : 4;
} TS_packet_header;

解析:

数据长度数据含义
sync_byte8bit同步字节,一般是0x47
transport_error_indicator1bit该位值为1时,表示在相关的传送包中至少有一个不可纠正的错误,只有在错误纠正之后,该位才能被重新置0。
payload_unit_start_indicator1bit该字段用来表示TS包的有效净荷有PES包或者PSI数据的情况。payload_unit_start_indicator为1时,在前4个字节之后会有一个调整字节,它的数值决定了负载内容的具体开始位置。例如:47 40 00 17 00第五个字节是00,说明紧跟着00之后就是具体的负载内容(有效负载)。
transport_priority1bit传输优先级,1为高优先级
PID12bitPacket ID号码,唯一的号码对应不同的包
transport_scrambling_control2bit加密标志(00:未加密;其他表示已加密)
adaptation_field_control2bit表示传送流包首部是否跟随有调整字段。01仅含有效负载,10仅含调整字段,11含有调整字段和有效负载。为00的话解码器不进行处理。
continuity_counter4bit范围0-15,具有相同的PID的TS分组传输时每次加1,到15后清0。不过,有些情况下是不计数的。如下:(1)TS分组无有效负载。(2)复制的TS分组和原分组这个值一样。(3)标志discontinuity_indicator为1时。

参考:

http://www.cnblogs.com/shakin/p/3714848.html
http://www.cnblogs.com/jiangzhaowei/p/3625944.html

TS流调整参考:http://blog.csdn.net/cabbage2008/article/details/49837143
较详细的数据结构:http://blog.csdn.net/a31898534/article/details/4399353

可用以下代码结合上文协同了解(http://blog.csdn.net/a31898534/article/details/4399353 )。

transport_packet() {sync_byte                                                                    // 8transport_error_indicator                                          //1payload_unit_start_indicator                                    //1transport_priority                                                       // 1PID                                                                             //13transport_scrambling_control                                  // 2adaptation_field_control                                            //2continuity_counter                                                      //4if(adaptation_field_control=='10'  || adaptation_field_control=='11') {adaptation_field()}if(adaptation_field_control=='01' || adaptation_field_control=='11') {for (i=0; i<N; i++) {data_byte                                                                   //8}}
}

2. BAT表语法解析

2.1 BAT表简介

BAT表的一个片段如下(包含表头,不含TS包的同步字节内容)

PositionHexText
00004a f2 ed 70 11 ff 00 00 f2 e0 47 08 64 61 74 61 63 61J…p…G.dataca
001273 74 4a f5 00 01 00 01 a0 01 80 02 00 90 5f 00 00 00stJ…_…
002400 01 02 00 02 07 00 03 07 00 04 07 00 05 07 00 06 01
003600 07 01 00 08 01 00 09 01 00 0a 01 00 0b 08 00 0c 08
004800 0d 08 00 0e 08 00 0f 03 00 10 00 00 11 00 00 12 00

2.2 BAT表的语法和解析

BAT表语法如下:

语法表中(只说明几个重要的):

语法长度(Bit)解析
table_id8用于确定表类型,0x4A代表bouquet_association_section
section_syntax_indicator1段语法标志,此处必须是1
section_length12段长,单位Byte
bouquet_id16Bouquet表ID,在数据广播中此处为0x7011
version_number5数据版本号,从0起递增,到1f后归零
current_next_indicator1置于‘1’时指示发送的有条件访问表为当前有效的。该比特设置为‘0’时,它指示发送的有条件访问表尚未有效并且下一个有条件访问表将生效
section_number8(分段传输表时的)本段编号,第一段表编号应为0x00
last_section_number8最后一段编号
descriptor-描述符

|CRC32|4|从表头到数据的最后一字节的CRC32校验,算法使用CRC32/MPEG-2

上图中从最后一个reserved_future_use到最后的CRC32前的大括号均未在此出现

按照上述表格解析例子中的BAT表,得出以下结果(descriptor部分在后文进行分析):

2.3 链接描述符linkage_descriptor

在上文给出的例子中,从0xa开始的内容是链接描述符。

链接描述符的语法如下:

其中值得注意的是:

  • descriptor_tag:在这里有两种descriptor_tag。tag = 0x47是表名,不用注意此段数据。tag = 0x4A才是值得注意的数据。
  • linkage_type:链接类型,在这里是0x80。
  • PID:文件信息所在的PID。
  • table_ext_id:实际上就是文件编号
  • last_section_num:该文件编号对应的文件在传输中的总段数

2.4 解析用途

对BAT表的解析主要是为了了解一下信息:

  1. 文件内容所在的PID
  2. 文件总数和每个文件总段数。

3. CRC32/MPEG2校验

3.1 CRC32/MPEG2参数模型

该校验的参数模型如下:

其中各参数定义:

  • NAME:名称

  • WIDTH:宽度,即CRC比特数

  • POLY:生成项的简写。以16进制表示,即是0x04C11DB7。忽略了最高位的"1",即完整的生成项是0x104C11DB7。重要的一点是,这是“未颠倒”的生成项!前面说过,“颠倒的”生成项是0xEDB88320。

  • INIT:这是算法开始时寄存器的初始化预置值,十六进制表示。这个值可以直接赋值给“直驱表法”算法中的寄存器,作为寄存器的初始值!
    而对于“驱动表法”算法及“直接计算法”,寄存器的初始值必须是0!前面几次循环先将待测数据移入到寄存器中,当寄存器装满后,再用这个初始化预置值去XOR寄存器,这样寄存器就被这个值初始化了!
    这点很重要!!如果在“驱动表法”算法开始时,寄存器的初始值不为0,那么寄存器中的值就会相当于是待测数据了,这样算出的CRC结果就不对了!我们的目的是用预置值去初始化寄存器,而不是将预置值作为待测数据去处理!

  • REFIN 这个值是真TRUE或假FALSE。
    如果这个值是FALSE,表示待测数据的每个字节都不用“颠倒”,即BIT7仍是作为最高位,BIT0作为最低位。
    如果这个值是TRUE,表示待测数据的每个字节都要先“颠倒”,即BIT7作为最低位,BIT0作为最高位。

  • REFOUT:这个值是真TRUE或假FALSE。
    如果这个值是FALSE,表示计算结束后,寄存器中的值直接进入XOROUT处理即可。
    如果这个值是TRUE,表示计算结束后,寄存器中的值要先“颠倒”,再进入XOROUT处理。注意,这是将整个寄存器的值颠倒,因为寄存器的各个字节合起来表达了一个值,如果只是对各个字节各自颠倒,那结果值就错误了。

  • XOROUT:这是W位长的16进制数值。
    这个值与经REFOUT后的寄存器的值相XOR,得到的值就是最终正式的CRC值!

参考:http://www.360doc.com/content/14/0513/22/7991404_377367845.shtml

3.2 CRC32/MPEG2校验的Java实现

算法的实现使用CRC32表的方式,整体代码如下:

public class TsCRC32Utils {static final long[] CrcTable = {0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};public static int CRC32(byte[] indata) {int i;int crc = 0xFFFFFFFF;for(i = 0; i < indata.length; i++)crc = (int) ((crc << 8) ^ CrcTable[(int) (((crc >> 24) ^ indata[i]) & 0xFF)]);return crc;}
}

4. ABS文件内容的获取

ABS文件内容所在的PID可通过分析BAT表来读取。

此处的PID为0x200。

4.1 语法分析


先放一段例子进行分析:

000005c0h: 90 B6 3E 0E 4F FF 00 00 0F 32 32 38 5F 32 33 34 ; 惗>.O...228_234
000005d0h: 5F 30 30 37 2E 78 6D 6C 00 00 06 21 3C 3F 78 6D ; _007.xml...!<?xm
000005e0h: 6C 20 76 65 72 73 69 6F 6E 3D 22 31 2E 30 22 20 ; l version="1.0" 

table_id:此处必定是0x90。
section_syntax_indicator:必须是1。
section_length:本段长度(Byte)。
table_id_ext:文件编号(和BAT表里的保持一致)
section_number:当前段编号
last_section_number:最后一段编号,和BAT表里的信息一致
file_data_length:文件长度(注意:这里的文件长度是指本段的长度)

4.2 注意事项

  1. 实际使用时必须使用CRC32/MPEG-2校验接收到的数据。
  2. 注意判断文件是否接收完成。
  3. 注意内存的使用情况。

这篇关于BAT表、链接描述符、文件内容与CRC32/MPEG-2校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/187742

相关文章

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

Python FastAPI实现JWT校验的完整指南

《PythonFastAPI实现JWT校验的完整指南》在现代Web开发中,构建安全的API接口是开发者必须面对的核心挑战之一,本文将深入探讨如何基于FastAPI实现JWT(JSONWebToken... 目录一、JWT认证的核心原理二、项目初始化与环境配置三、安全密码处理机制四、JWT令牌的生成与验证五、

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

Spring Validation中9个数据校验工具使用指南

《SpringValidation中9个数据校验工具使用指南》SpringValidation作为Spring生态系统的重要组成部分,提供了一套强大而灵活的数据校验机制,本文给大家介绍了Spring... 目录1. Bean Validation基础注解常用注解示例在控制器中应用2. 自定义约束验证器定义自

全解析CSS Grid 的 auto-fill 和 auto-fit 内容自适应

《全解析CSSGrid的auto-fill和auto-fit内容自适应》:本文主要介绍了全解析CSSGrid的auto-fill和auto-fit内容自适应的相关资料,详细内容请阅读本文,希望能对你有所帮助... css  Grid 的 auto-fill 和 auto-fit/* 父元素 */.gri

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm