OggFile's CRC checksum
博客专区 > UMU 的博客 > 博客详情
OggFile's CRC checksum
UMU 发表于3个月前
OggFile's CRC checksum
  • 发表于 3个月前
  • 阅读 32
  • 收藏 0
  • 点赞 0
  • 评论 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
共有 人打赏支持
粉丝 106
博文 96
码字总数 40136
×
UMU
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: