可以优化PHP CRC例程的速度吗?

时间:2014-11-01 15:26:56

标签: php optimization crc

如果30个第一个字节的CRC等于最后两个字节中的(EBU)crc值,则该例程返回0。在我的服务器上,脚本有点慢,所以我想知道这个例程是否可以优化。

如果我故意让它在86500行32字节数据上失败,如果我取消注释第一次返回,我的程序将在2.2秒内结束。如果我取消评论第二次返回,则以4.4秒结束;如果我取消评论第三次返回,则以5.8秒结束。我想跳过解压缩会很好,但我所有的尝试都失败了。

CRC例程本身就在网上找到了。感谢无论是谁写的!

function crc($datax)
{
    //return 1; // First return
    global $row;
    $data = unpack('C*', $datax); // unpack seems to start with index 1...
    //return 1; // Second return
    $crc = 0xFFFF;
    for ($i = 1; $i < 31; $i++) {
        $x = (($crc >> 8) ^  $data[$i] ) & 0xFF;
        $x ^= $x >> 4;
        $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x);
    }
    //return 1; // Third return
    return ( (~$crc & 0xFFFF ) - $data[31] * 256 - $data[32] );
}

,数据来自

$fib = fread($fp, 32);
if ( crc16( $fib ) == 0 ) {
   ; // process data...
}

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用表驱动方法,这种方法稍快一些。这可以帮助您达到~$crc & 0xFFFF的目的。之后的减去值不是实际CRC的一部分。

$crc16epc_table = array(
    0x1e0f, 0x0e2e, 0x3e4d, 0x2e6c, 0x5e8b, 0x4eaa, 0x7ec9, 0x6ee8,
    0x9f07, 0x8f26, 0xbf45, 0xaf64, 0xdf83, 0xcfa2, 0xffc1, 0xefe0,
    0x0c3e, 0x1c1f, 0x2c7c, 0x3c5d, 0x4cba, 0x5c9b, 0x6cf8, 0x7cd9,
    0x8d36, 0x9d17, 0xad74, 0xbd55, 0xcdb2, 0xdd93, 0xedf0, 0xfdd1,
    0x3a6d, 0x2a4c, 0x1a2f, 0x0a0e, 0x7ae9, 0x6ac8, 0x5aab, 0x4a8a,
    0xbb65, 0xab44, 0x9b27, 0x8b06, 0xfbe1, 0xebc0, 0xdba3, 0xcb82,
    0x285c, 0x387d, 0x081e, 0x183f, 0x68d8, 0x78f9, 0x489a, 0x58bb,
    0xa954, 0xb975, 0x8916, 0x9937, 0xe9d0, 0xf9f1, 0xc992, 0xd9b3,
    0x56cb, 0x46ea, 0x7689, 0x66a8, 0x164f, 0x066e, 0x360d, 0x262c,
    0xd7c3, 0xc7e2, 0xf781, 0xe7a0, 0x9747, 0x8766, 0xb705, 0xa724,
    0x44fa, 0x54db, 0x64b8, 0x7499, 0x047e, 0x145f, 0x243c, 0x341d,
    0xc5f2, 0xd5d3, 0xe5b0, 0xf591, 0x8576, 0x9557, 0xa534, 0xb515,
    0x72a9, 0x6288, 0x52eb, 0x42ca, 0x322d, 0x220c, 0x126f, 0x024e,
    0xf3a1, 0xe380, 0xd3e3, 0xc3c2, 0xb325, 0xa304, 0x9367, 0x8346,
    0x6098, 0x70b9, 0x40da, 0x50fb, 0x201c, 0x303d, 0x005e, 0x107f,
    0xe190, 0xf1b1, 0xc1d2, 0xd1f3, 0xa114, 0xb135, 0x8156, 0x9177,
    0x8f87, 0x9fa6, 0xafc5, 0xbfe4, 0xcf03, 0xdf22, 0xef41, 0xff60,
    0x0e8f, 0x1eae, 0x2ecd, 0x3eec, 0x4e0b, 0x5e2a, 0x6e49, 0x7e68,
    0x9db6, 0x8d97, 0xbdf4, 0xadd5, 0xdd32, 0xcd13, 0xfd70, 0xed51,
    0x1cbe, 0x0c9f, 0x3cfc, 0x2cdd, 0x5c3a, 0x4c1b, 0x7c78, 0x6c59,
    0xabe5, 0xbbc4, 0x8ba7, 0x9b86, 0xeb61, 0xfb40, 0xcb23, 0xdb02,
    0x2aed, 0x3acc, 0x0aaf, 0x1a8e, 0x6a69, 0x7a48, 0x4a2b, 0x5a0a,
    0xb9d4, 0xa9f5, 0x9996, 0x89b7, 0xf950, 0xe971, 0xd912, 0xc933,
    0x38dc, 0x28fd, 0x189e, 0x08bf, 0x7858, 0x6879, 0x581a, 0x483b,
    0xc743, 0xd762, 0xe701, 0xf720, 0x87c7, 0x97e6, 0xa785, 0xb7a4,
    0x464b, 0x566a, 0x6609, 0x7628, 0x06cf, 0x16ee, 0x268d, 0x36ac,
    0xd572, 0xc553, 0xf530, 0xe511, 0x95f6, 0x85d7, 0xb5b4, 0xa595,
    0x547a, 0x445b, 0x7438, 0x6419, 0x14fe, 0x04df, 0x34bc, 0x249d,
    0xe321, 0xf300, 0xc363, 0xd342, 0xa3a5, 0xb384, 0x83e7, 0x93c6,
    0x6229, 0x7208, 0x426b, 0x524a, 0x22ad, 0x328c, 0x02ef, 0x12ce,
    0xf110, 0xe131, 0xd152, 0xc173, 0xb194, 0xa1b5, 0x91d6, 0x81f7,
    0x7018, 0x6039, 0x505a, 0x407b, 0x309c, 0x20bd, 0x10de, 0x00ff
);

function crc16epc($string)
{
    $bytes = unpack("C*", $string);
    $crc = 0;
    foreach ($bytes as $next)
        $crc = ($crc << 8) ^ $GLOBALS['crc16epc_table'][(($crc >> 8) ^ $next) & 0xff];
    return $crc & 0xffff;
}