2014-11-01 5 views
0

Эта процедура возвращает 0, если CRC из 30 первых байтов равен значению crc (EBU) в последних двух байтах. На моем сервере сценарий немного медленный, поэтому я хочу знать, можно ли оптимизировать эту процедуру.Возможно оптимизировать скорость PHP CRC-рутин?

Если я намеренно отказываюсь на 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... 
} 

Спасибо!

+0

В чем смысл определения глобальной '$ row'? Вы не используете его вообще –

+0

Вы абсолютно правы, я сам не видел. К сожалению, это не помогло миллисекунде удалить эту линию. – dotswe

+0

Использование предварительного приращения может показаться микро-оптимизацией, но 'for ($ i = 1; $ i <31; ++ $ i)' может сэкономить несколько наносекунд –

ответ

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; 
} 
+0

Должна быть опечатка, потому что я получаю одно и то же значение crc для каждой строки, которую я запускаю. Вот одна строка примеров данных [code] (массив (1 => 5, 2 => 0, 3 => 224, 4 => 1, 5 => 49, 6 => 218, 7 => 8, 8 = > 40, 9 => 227, 10 => 228, 11 => 1, 12 => 1, 13 => 0, 14 => 129, 15 => 1, 16 => 13, 17 => 8, 18 = > 226, 19 => 12, 20 => 0, 21 => 12, 22 => 224, 23 => 53, 24 => 0, 25 => 6, 26 => 226, 27 => 7, 28 = > 0, 29 => 7, 30 => 255, 31 => 112, 32 => 97,) crc16epc возвращает: 58096 crc16 возвращает: 36766) Я протестировал для инициализации 'code' ($ crc) с обоими 0 и FFFF. Благодаря! – dotswe

+0

Вы видели, что я сказал о том, что делает эта процедура по сравнению с вашей? Вы должны дать 'crc16epc()' только первые 30 байтов вашей 32-байтовой строки. Когда я это делаю, я получаю 28769 за CRC. Это на самом деле равно 112 * 256 + 97 (последние два байта вашей 32-байтовой строки, объединенные). Я не знаю, что вы подразумеваете под 'crc16', так как ваш вопрос имеет только функцию' crc'. –

+0

.'$ test = array (5, 0, 224, 1, 49, 218, 8, 40, 227, 228, 1, 1, 0, 129, 1, 13, 8, 226, 12, 0, 12, 224, 53, 0, 6, 226, 7, 0, 7, 255); $ teststr = implode (array_map ("chr", $ test)); $ crc = crc16epc ($ teststr); printf ("len =% d, crc =% d = 0x% s
", strlen ($ teststr), $ crc, dechex ($ crc)); 'дает' len = 30, crc = 28769 = 0x7061'. –

 Смежные вопросы

  • Нет связанных вопросов^_^