javascript - 如何为Ogg建立CRC32表?

标签 javascript crc ogg crc32

来自this answer我修改了下面的代码:

function _makeCRCTable() {
    const CRCTable = new Uint32Array(256);
    for (let i = 256; i--;) {
        let char = i;
        for (let j = 8; j--;) {
            char = char & 1 ? 3988292384 ^ char >>> 1 : char >>> 1;
        }
        CRCTable[i] = char;
    }
    return CRCTable;
}

此代码生成table as here ,但对于 Ogg 我需要另一个表 - 如 here .

来自Ogg documentation :

32 bit CRC value (direct algorithm, initial val and final XOR = 0, generator polynomial=0x04c11db7)

parseInt('04c11db7', 16)

返回79764919 - 我尝试了这个多项式,但结果表不正确。

我是 CRC 领域的新手,我发现 there are a few variations of CRC32 algorithm .

最佳答案

我不确定 JavaScript 的优先级,但异或需要在移位之后发生:

char = char & 1 ? 3988292384 ^ (char >>> 1) : char >>> 1;

但是,您显示的第一个表似乎是正确的,因为 table[128] = table[0x80] = 3988292384 = 0xEDB88320 是 0x104c11db7 位反转,然后右移一位。

您拥有的第二个表用于左移 CRC,其中 table[1] = x04c11db7。在这种情况下,内部循环将包括如下内容:

let char = i << 24;
for (let j = 8; j--;) {
    char = char & 0x80000000 ? 0x04c11db7 ^ char << 1 : char << 1;
}
<小时/>

用于比较的示例 C 代码,为模式 {0x01}、{0x01,0x00}、{0x01,0x00,0x00}、{0x01,0x00,0x00,0x00} 生成 crc。

#include <stdio.h>

typedef unsigned char uint8_t;
typedef unsigned int  uint32_t;

uint32_t crctbl[256];

void gentbl(void)
{
uint32_t crc;
uint32_t b;
uint32_t c;
uint32_t i;
    for(c = 0; c < 0x100; c++){
        crc = c<<24;
        for(i = 0; i < 8; i++){
            b = crc>>31;
            crc <<= 1;
            crc ^= (0 - b) & 0x04c11db7;
        }
        crctbl[c] = crc;
    }
}

uint32_t crc32(uint8_t * bfr, size_t size)
{
uint32_t crc = 0;
    while(size--)
        crc = (crc << 8) ^ crctbl[(crc >> 24)^*bfr++];
    return(crc);
}

int main(int argc, char** argv)
{
    uint32_t crc;
    uint8_t bfr[4] = {0x01,0x00,0x00,0x00};
    gentbl();
    crc = crc32(bfr, 1);        /* 0x04c11db7 */
    printf("%08x\n", crc);
    crc = crc32(bfr, 2);        /* 0xd219c1dc */
    printf("%08x\n", crc);
    crc = crc32(bfr, 3);        /* 0x01d8ac87 */
    printf("%08x\n", crc);
    crc = crc32(bfr, 4);        /* 0xdc6d9ab7 */
    printf("%08x\n", crc);
    return(0);
}

对于 JS:

function _makeCRC32Table() {
    const polynomial = 79764919;
    const mask = 2147483648;
    const CRCTable = new Uint32Array(256);
    for (let i = 256; i--;) {
        let char = i << 24;
        for (let j = 8; j--;) {
            char = char & mask ? polynomial ^ char << 1 : char << 1;
        }
        CRCTable[i] = char;
    }
    return CRCTable;
}

如何使用此表:

[1, 0].reduce((crc, byte) => crc << 8 >>> 0 ^ CRCTable[crc >>> 24 ^ byte], 0) >>> 0

这里我们添加了 >>> 0 来取数字的模 - 因为 JS 中没有 unsigned int - JavaScript doesn't have integers. It only has double precision floating-point numbers .

请注意,对于 Ogg,您必须以相反的顺序设置生成的 CRC。

关于javascript - 如何为Ogg建立CRC32表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53438815/

相关文章:

javascript - 为什么回调函数中 "this"指向 "window Object"呢?

验证动态字节数组的 CRC 时崩溃 | C

python - 在Python中检查字节校验和的最佳方法

ffmpeg - Android Chrome 支持哪种ogg?

javascript - 如何更改显示图像的 div 的大小

javascript - 检测移动缩放和默认移动分辨率

javascript - embed.fields[1].value : Must be 1024 or fewer in length. embed.fields[2].value: 长度必须为 1024 或更少

algorithm - 当我们在CRC32中使用CLMUL时,位反射(reflect)常数是如何计算的?

HTML5 <audio> 不适用于 Firefox,即使我使用 .ogg

php - PHP 中的 Wav 到 Ogg 或 MP3