Python和C的crc32相同

Raf*_*ski 2 c python crc32

我需要的脚本将使用Python和C的相同输出计算crc32.

我现在正在使用zlib.crc32,但是对于C,没有这样的库,我们基于维基百科自己编写它.但它没有返回相同的值.

这是我们的C脚本代码(从维基百科复制,基于RFC):

unsigned int crc32( unsigned char *message, unsigned int n )
{
   //int i, crc;
   unsigned int crc;
   unsigned int i;
   unsigned int byte, c;
   const unsigned int g0 = 0xEDB88320,    g1 = g0>>1,
      g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5,
      g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1;

   i = 0;
   crc = 0xFFFFFFFF;
   //while ((byte = message[i]) != 0)
   while( i != n)
   {
               byte = message[i];                   // Get next byte.
               // byte = FrmReadByte( i );  // Get next byte.

               crc = crc ^ byte;
               c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^
               ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^
               ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^
               ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0);

               crc = ((unsigned)crc >> 8) ^ c;
               i = i + 1;
   }
   return ~crc;
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我们只有4KB的ram内存,程序本身并不存在.通过crc32脚本占用1KB的内存可能太多而且不适合那里.感谢您指出ZLIB库也存在于C中.

Mar*_*ler 10

我现在正在使用zlib.crc32,但对于C,没有这样的库

嗯,是的,有.它被称为zlib.zlib是用C语言编写的,它正是Python所使用的!因此,班级的名称.

您可以crc32()在zlib中使用该函数.这种实现比您可能找到的其他实现快一点.请阅读zlib.h以获取接口信息.

您可以自己编译zlib,或者它可能已经安装在您的系统上.

更新:

我现在看到你的评论(应该编辑成问题,因为它对于获得正确的答案至关重要)你的内存非常有限.然后你可以使用这个:

static uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len)
{
    int k;

    crc = ~crc;
    while (len--) {
        crc ^= *buf++;
        for (k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
    }
    return ~crc;
}
Run Code Online (Sandbox Code Playgroud)

crc最初设置为零.

使用~将得到正确的结果,因为uint32_t输入stdint.h确保为32位.

如果你能承受更多的代码空间,那么展开循环可能会加快它的速度(如果编译器还没有这样做):

static uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len)
{
    crc = ~crc;
    while (len--) {
        crc ^= *buf++;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
    }
    return ~crc;
}
Run Code Online (Sandbox Code Playgroud)

你说你只有4 KB的"记忆".这只是程序的工作记忆,还是程序也必须住在那里?例如,如果代码中有更多闪存空间,则表可以预先计算并与代码一起存储.表驱动的CRC将更快.zlib代码提供表驱动的CRC,一次执行一个字节,一次执行四个字节,分别需要1Kbyte或4Kbyte表.

更新2:

由于您在评论中回答4KBytes只是工作内存,因此您应该使用表驱动的CRC.你可以简单地使用crc32()在zlib的的功能crc32.c,并在表中crc32.hBYFOUR定义.