文档章节

OggFile's CRC checksum

UMU
 UMU
发布于 2017/08/02 22:31
字数 479
阅读 34
收藏 0

这几天研究 live555,然而蛋疼滴发现它流化的 opus 文件,VLC 居然无法播放,于是想了解一下 opus 文件,看了 live555 的 OggFileParser 代码,发现 checksum 都被无视了,本来 UMU 也应该无视这个细节的,然而随便用自己以前写的 CRC32 代码验证了一下,居然不一样!而这份代码之前是测试过的,和 7-Zip 的 CRC-32 算出来是一致的。

因为 opus 文件是基于 ogg 文件格式的,所以阅读了一下 Ogg Documentation,发现确实不一样,它用的其实是 CRC32_IEEE,于是参考了 libogg 的 framing.c 和 ffmpeg\libavutil\crc.c 把自己的代码库给更新了,使用模版增强功能:

#pragma region "CRC"
// CRC_8_ATM        <false,  8,       0x07, 0>
// CRC_16_ANSI      <false, 16,     0x8005, 0>
// CRC_16_CCITT     <false, 16,     0x1021, 0>
// CRC_24_IEEE      <false, 24,   0x864CFB, 0>
// CRC_32_IEEE      <false, 32, 0x04C11DB7, 0>  -> OggFile's Checksum
// CRC_32_IEEE_LE   <true,  32, 0xEDB88320, 0>
// CRC_16_ANSI_LE   <true,  16,     0xA001, 0>
// defualt          <true,  32, 0xEDB88320, 0xFFFFFFFF>, 7 - Zip's CRC-32
template <bool kIsLE = true, uint8_t kBits = 32, uint32_t kPolynomial = 0xEDB88320, uint32_t kXorOut = 0xFFFFFFFF>
class CRC
{
public:
    CRC()
    {
        static_assert (kBits >= 8 && kBits <= 32 && kPolynomial < (1LL << kBits), "invalid bits");

        for (int i = 0; i < 256; ++i) {
            if (kIsLE) {
                register uint32_t crc = i;
                for (int j = 8; j > 0; --j) {
                    crc = (crc >> 1) ^ (kPolynomial & (-static_cast<int32_t>(crc & 1)));
                }
                crc32_table_[i] = crc;
            } else {
                register uint32_t crc = i << 24;
                for (int j = 8; j > 0; --j) {
                    crc = (crc << 1) ^ ((kPolynomial << (32 - kBits)) & (static_cast<int32_t>(crc) >> 31));
                }
                crc32_table_[i] = be2me_32(crc);
            }
        }
    }

    uint32_t GetCRC(uint32_t crcinit, const uint8_t* data, size_t data_size)
    {
        register uint32_t crc = crcinit ^ kXorOut;

        /* process not aligned message head */
        for (; (3 & (data - (uint8_t*)0)) && data_size > 0; ++data, --data_size) {
            crc = crc32_table_[static_cast<uint8_t>(crc) ^ *data] ^ (crc >> 8);
        }

        /* fast CRC32 calculation of a DWORD-aligned message */
        for (const uint8_t* e = data + (data_size & ~15); data < e; data += 4) {
            crc ^= le2me_32(*reinterpret_cast<const uint32_t *>(data));
            crc = crc32_table_[crc & 0xFF] ^ (crc >> 8);
            crc = crc32_table_[crc & 0xFF] ^ (crc >> 8);
            crc = crc32_table_[crc & 0xFF] ^ (crc >> 8);
            crc = crc32_table_[crc & 0xFF] ^ (crc >> 8);
        }

        /* process not aligned message tail */
        for (const uint8_t* e = data + (data_size & 15); data < e; ++data) {
            crc = crc32_table_[static_cast<uint8_t>(crc) ^ *data] ^ (crc >> 8);
        }
        return crc ^ kXorOut;
    }

private:
    uint32_t crc32_table_[256];
};
#pragma endregion

© 著作权归作者所有

共有 人打赏支持
UMU

UMU

粉丝 117
博文 112
码字总数 44043
作品 0
厦门
程序员
批量替换目录中的文件内容

将目录下所有以0开头的文件中的英文逗号替换为中文逗号,再将$替换为英文逗号,注意这里要将.000开头,.crc结尾的文件排除在外,因为这些是校验文件,修改后,再次往hive中导入文件的时候,会...

sucre
2016/07/11
21
0
mysql主从一致性检测和修复

一、 简介 pt-table-checksum是著名的 percona-toolkit 工具集的工具之一。它通过在主库执行基于statement的sql语句来生成主库数据块的checksum,把相同的sql语句传递到从库,并在从库上计算...

stone_
2016/07/28
169
0
MySQL主从的一致性校验及修复

主从的一致性校验 场景: 有人会问道:如何验证主从的一致性 又或者问:一个库里有几十张表 主从结构数据是否一致? 简单来讲可以在低峰期主从上分别使用select count(*)来看一下,这种方式...

zuzhou
2015/01/21
0
0
TCP Protocol Layers Explained

Now that we've examined what is contained in a Layer 3 (IP) header, let's move on to the Layer 4 header. A Layer 4 header occurs at the very beginning of the IP data field and c......

小小鸟你妈
2014/07/11
0
0
wireshark抓包大于1500字节和提示checksum offload的原因

问题: wireshark抓包大于1500字节(如下图所示) wireshark抓包提示:[incorrect, should be xxxx (maybe caused by "TCP checksum offload"?)] 原因: wireshark是在数据包经过cpu,送到网...

tutor
07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

谈谈神秘的ES6——(五)解构赋值【对象篇】

上一节课我们了解了有关数组的解构赋值相关内容,这节课,我们接着,来讲讲对象的解构赋值。 解构不仅可以用于数组,还可以用于对象。 let { foo, bar } = { foo: "aaa", bar: "bbb" };fo...

JandenMa
19分钟前
0
0
OSChina 周一乱弹 —— 有人要给本汪介绍妹子啦

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享水木年华的单曲《中学时代》@小小编辑 手机党少年们想听歌,请使劲儿戳(这里) @须臾时光:夏天还在做最后的挣扎,但是晚上...

小小编辑
26分钟前
5
1
centos7安装redis及开机启动

配置编译环境: sudo yum install gcc-c++ 下载源码: wget http://download.redis.io/releases/redis-3.2.8.tar.gz 解压源码: tar -zxvf redis-3.2.8.tar.gz 进入到解压目录: cd redis-3......

hotsmile
48分钟前
0
0
PopupWindow总结和通用PopupWindow

PopupWindow 注意点: 设置PopupWindow的宽高,容易忘记,没有设置宽高在某些情况下会不展示。 基础设置少不了 pop.setBackgroundDrawable(new BitmapDrawable());pop.setFoucusable(true)...

DaSheng丶
56分钟前
0
0
Confluence 6 数据库和临时目录

数据库 所有的其他数据库,包括有页面,内容都存储在数据库中。如果你安装的 Confluence 是用于评估或者你选择使用的是 Embedded H2 Database 数据库。数据库有关的文件将会存储在 database...

honeymose
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部