4

我需要帮助将 C 代码转换为 PHP。以下是C代码:

static const U16 crctab16[] = { 0x0000, 0x1189, ... };

U16 GetCrc16(const U8* pData, int nLength)
{
  U16 fcs = 0xffff;
  while(nLength > 0)
  {
    fcs = (fcs >> 8) ^ crctab16[fcs ^ *pData) & 0xff];
    nLength--; pData++;
  }
  return ~fcs;
}

到目前为止,我已经设法转换了以下 PHP 代码:

$crctab16 = array(0x0000, 0x1189, ... );

function getCrc16($pData)
{
    $hexdata = pack('H*',$pData);
    $nLength = strlen($hexdata);
    $fcs = 0xFFFF;
    $pos = 0;
    while($nLength > 0)
    {
        $fcs = ($fcs >> 8) ^ $crctab16[($fcs ^ $hexdata[$pos]) & 0xFF];
        $nLength--;
        $pos++;
    }
    return ~$fcs;
}

我试图运行以下代码:

$str = "0A1344010400010005"; 
var_dump(getCrc16($str));
var_dump(bin2hex(getCrc16($str))); // result supposed to be 08 45

它似乎显示了错误的结果。当我尝试$str用其他值替换时,结果将始终相同。

我相信我的 PHP 代码可能有问题。但是,我似乎无法弄清楚造成这种情况的原因。

4

3 回答 3

2

试试这个

function crc16($sStr, $aParams = array()){ 

 $aDefaults = array( 
   "polynome" => 0x1021, 
   "init" => 0xFFFF, 
   "xor_out" => 0, 
 ); 

 foreach ($aDefaults as $key => $val){ 
   if (!isset($aParams[$key])){ 
     $aParams[$key] = $val; 
   } 
 } 

 $sStr .= ""; 
 $crc = $aParams['init']; 
 $len = strlen($sStr); 
 $i = 0; 

 while ($len--){ 
   $crc ^= ord($sStr[$i++]) << 8; 
   $crc &= 0xffff; 

   for ($j = 0; $j < 8; $j++){ 
     $crc = ($crc & 0x8000) ? ($crc << 1) ^ $aParams['polynome'] : $crc << 1; 
     $crc &= 0xffff; 
   } 
 } 

 $crc ^= $aParams['xor_out']; 

 return $crc; 
}
于 2012-06-18T07:31:20.883 回答
2

我已经设法找出解决方案。感谢@nhahtdh、@Carsten 和@odiszapc,他们提供了帮助。

这是正确的 PHP 函数:

function getCrc16($pData)
{
    $hexdata = pack('H*',$pData);
    $nLength = strlen($hexdata);
    $fcs = 0xFFFF;
    $pos = 0;
    while($nLength > 0)
    {
        $fcs = ($fcs >> 8) ^ $crctab16[($fcs ^ ord($hexdata[$pos])) & 0xFF];
        $nLength--;
        $pos++;
    }
    return ~$fcs;
}

看来我需要ord()在字节格式数据中起作用。我在@Carsten 提供的 CRC16 示例之后发现了这一点。

十分感谢大家!

于 2012-06-18T08:44:01.850 回答
0
Code fragment of the CRC-ITU lookup table algorithm implemented based on C language is as follow: 

static const U16 crctab16[] = {     0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF,     0X8C48, 0X9DC1, 0XAF5A, 0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7,     0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C, 0X75B7, 0X643E,     0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876,     0X2102, 0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD,     0XAD4A, 0XBCC3, 0X8E58, 0X9FD1, 0XEB6E, 0XFAE7, 0XC87C, 0XD9F5,     0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5, 0X453C,     0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974,     0X4204, 0X538D, 0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB,     0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868, 0X99E1, 0XAB7A, 0XBAF3,     0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A,     0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72,     0X6306, 0X728F, 0X4014, 0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9,     0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3, 0X8A78, 0X9BF1,     0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738,     0XFFCF, 0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70,     0X8408, 0X9581, 0XA71A, 0XB693, 0XC22C, 0XD3A5, 0XE13E, 0XF0B7,     0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76, 0X7CFF,     0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036,     0X18C1, 0X0948, 0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E,     0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E, 0XF2A7, 0XC03C, 0XD1B5,     0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD,     0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134,     0X39C3, 0X284A, 0X1AD1, 0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C,     0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1, 0XA33A, 0XB2B3,     0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB,     0XD68D, 0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232,     0X5AC5, 0X4B4C, 0X79D7, 0X685E, 0X1CE1, 0X0D68, 0X3FF3, 0X2E7A,     0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238, 0X93B1,     0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9,     0XF78F, 0XE606, 0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330,     0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3, 0X2C6A, 0X1EF1, 0X0F78, }; 

//  calculate the 16-bit CRC of data with predetermined length.

U16 GetCrc16(const U8* pData, int nLength) {     
  U16  fcs  =  0xffff;         //  initialization     
  while(nLength>0){         
    fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff];         
    nLength--;         
    pData++;     
  }     
  return  ~fcs;         //  negated 
} 
于 2017-06-20T15:20:21.367 回答