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

相关文章

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

校验码:奇偶校验,CRC循环冗余校验,海明校验码

文章目录 奇偶校验码CRC循环冗余校验码海明校验码 奇偶校验码 码距:任何一种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据检验码的码距。 奇偶校验码的编码方法是:由若干位有效信息(如一个字节),再加上一个二进制位(校验位)组成校验码。 奇校验:整个校验码中1的个数为奇数 偶校验:整个校验码中1的个数为偶数 奇偶校验,可检测1位(奇数位)的错误,不可纠错。

短链接算法原理

平时我们在上网的时候,印象最深刻的有一次是短链接的服务。例如:平时在微信上看一个网页的时候,如果我们选择在浏览器打开的时候,会看到很长的URL,我们分享的时候,会看到一个很短URL,这就是本次所说的短链接的应用之一。 长链接示例:https://mp.weixin.qq.com/s?__biz=MzAxNzMwOTQ0NA==&mid=2653355437&idx=1&sn=5901826ea63

Wondows dos下怎么编写bat批处理文件

最近搞php,在运行时,以Nginx+php-cgi.exe方式运行Wordpress项目 打开dos,先cd到php-cgi.exe文件当前目录下执行启动命令:php-cgi.exe -b 127.0.0.1:9001再打开一个dos,再cd到nginx.exe文件当前目录下执行启动命令:start nginx 大概过程要经过这些步骤,觉得很麻烦,就学下怎么编写一个bat文件,以双击运行代替

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正