2012-05-25 26 views
2

У меня есть проблема с этим алгоритмом:Перевести Matlab код на Python

function crc16 = crc16eval(D) 
% CRC16EVAL CRC-CCITT check with the polynomial: x^16+x^12+x^5+1 
D = uint16(D); 
crchi = 255; 
crclo = 255; 
t = '00102030405060708191a1b1c1d1e1f112023222524272629383b3a3d3c3f3e32434041464744454a5b58595e5f5c5d53626160676665646b7a79787f7e7d7c74858687808182838c9d9e9f98999a9b95a4a7a6a1a0a3a2adbcbfbeb9b8bbbab6c7c4c5c2c3c0c1cedfdcdddadbd8d9d7e6e5e4e3e2e1e0effefdfcfbfaf9f8f9181b1a1d1c1f1e110003020504070608393a3b3c3d3e3f30212223242526272b5a59585f5e5d5c53424140474645444a7b78797e7f7c7d72636061666764656d9c9f9e99989b9a95848786818083828cbdbebfb8b9babbb4a5a6a7a0a1a2a3afdedddcdbdad9d8d7c6c5c4c3c2c1c0cefffcfdfafbf8f9f6e7e4e5e2e3e0e1e'; 
crc16htab = hex2dec(reshape(t,2,length(t)/2)'); 
t = '0021426384a5c6e708294a6b8cadceef31107352b594f7d639187b5abd9cffde62432001e6c7a4856a4b2809eecfac8d53721130d7f695b45b7a1938dffe9dbcc4e586a740610223cced8eaf48690a2bf5d4b79671503312fddcbf9e79583b1aa687e4c522036041ae8feccd2a0b684997b6d5f4133251709fbeddfc1b3a597888a9caeb0c2d4e6f80a1c2e304254667b998fbda3d1c7f5eb190f3d235147756eacba8896e4f2c0de2c3a08166472405dbfa99b85f7e1d3cd3f291b0577615344c6d0e2fc8e98aab44650627c0e182a37d5c3f1ef9d8bb9a75543716f1d0b3922e0f6c4daa8be8c926076445a283e0c11f3e5d7c9bbad9f81736557493b2d1f0'; 
crc16ltab = hex2dec(reshape(t,2,length(t)/2)'); 
for k = 1:length(D) 
    ix = double(bitxor(crchi,D(k)))+1; 
    crchi = bitxor(crclo,crc16htab(ix)); 
    crclo = crc16ltab(ix); 
end 
crc16 = crchi*256+crclo; 
end 

Мне нужно перевести этот код на Python, и я сделал следующее:

def crc16eval(D): 
    crchi = 255 
    crclo = 255 
    t = '00102030405060708191a1b1c1d1e1f112023222524272629383b3a3d3c3f3e32434041464744454a5b58595e5f5c5d53626160676665646b7a79787f7e7d7c74858687808182838c9d9e9f98999a9b95a4a7a6a1a0a3a2adbcbfbeb9b8bbbab6c7c4c5c2c3c0c1cedfdcdddadbd8d9d7e6e5e4e3e2e1e0effefdfcfbfaf9f8f9181b1a1d1c1f1e110003020504070608393a3b3c3d3e3f30212223242526272b5a59585f5e5d5c53424140474645444a7b78797e7f7c7d72636061666764656d9c9f9e99989b9a95848786818083828cbdbebfb8b9babbb4a5a6a7a0a1a2a3afdedddcdbdad9d8d7c6c5c4c3c2c1c0cefffcfdfafbf8f9f6e7e4e5e2e3e0e1e' 
    # crc16htab = hex2dec(reshape(t,2,length(t)/2)'); 

    tarray = [int(n, 16) for n in t] # Recorro el string t, y por cada caracter creo un nuevo entero en el array 

    crc16htab = reshape(tarray, (2, (len(t)/2))).transpose() 
    #print crc16htab 

    t = '0021426384a5c6e708294a6b8cadceef31107352b594f7d639187b5abd9cffde62432001e6c7a4856a4b2809eecfac8d53721130d7f695b45b7a1938dffe9dbcc4e586a740610223cced8eaf48690a2bf5d4b79671503312fddcbf9e79583b1aa687e4c522036041ae8feccd2a0b684997b6d5f4133251709fbeddfc1b3a597888a9caeb0c2d4e6f80a1c2e304254667b998fbda3d1c7f5eb190f3d235147756eacba8896e4f2c0de2c3a08166472405dbfa99b85f7e1d3cd3f291b0577615344c6d0e2fc8e98aab44650627c0e182a37d5c3f1ef9d8bb9a75543716f1d0b3922e0f6c4daa8be8c926076445a283e0c11f3e5d7c9bbad9f81736557493b2d1f0' 
    # crc16ltab = hex2dec(reshape(t,2,length(t)/2)'); 

    tarray = [int(n, 16) for n in t] # Recorro el string t, y por cada caracter creo un nuevo entero en el array 

    crc16ltab = reshape(tarray, (2, (len(t)/2))).transpose() 
    #print crc16ltab 

    for k in range(len(D)): 
     ix = crchi^D[k] 
     crchi = crclo^crc16htab[ix] 
     crclo = crc16ltab[ix] 

    return crchi*256+crclo 

Моя проблема заключается в следующем :

Когда я выполняю от кода Python, это взять займет слишком много времени вычислить де XOR, я думаю, что проблема заключается в том, что

crclo = crc16ltab[ix] 

- это матрица, и это занимает много времени, чтобы вычислить. В чем проблема?

Псевдокод этого алгоритма является следующий:

The algorithm for the CRC-CCITT is below described. Note that all operations are on bytes. 
A = new byte 
B = temp byte 
CRCHI = High byte (most significant) of the 16-bit CRC 
CRCLO = Low byte (least significant) of the 16-bit CRC 
START: 
    FOR A = FIRST_BYTE TO LAST_BYTE IN BLOCK DO: 
     A = A XOR CRCHI 
     CRCHI = A 
     SHIFT A RIGHT FOUR TIMES (ZERO FILL) 
     A = A XOR CRCHI     {IJKLMNOP} 
     CRCHI = CRCLO     { swap CRCHI, CRCLO } 
     CRCLO = A 
     ROTATE A LEFT 4 TIMES   {MNOPIJKL} 
     B=A        { temp save } 
     ROTATE A LEFT ONCE    {NOPIJKLM} 
     A = A AND $1F     {000IJLLM} 
     CRCHI = A XOR CRCHI 
     A = B AND $F0     {MNOP0000} 
     CRCHI = A XOR CRCHI    { CRCHI complete } 
     ROTATE B LEFT ONCE    {NOP0000M} 
     B = B AND $ E0     {NOP00000} 
     CRCLO = B XOR CRCLO    { CRCLO complete } 
    DOEND; 
FINISH. 

Мой вопрос: Почему мой питон код займет много времени, чтобы выполнить? Что не так? Проблема, я думаю, находится в

for k in range(len(D)): 
    ix = crchi^D[k] 
    crchi = crclo^crc16htab[ix] 
    crclo = crc16ltab[ix] 

Большое спасибо!

+0

Это python2 или python3? Вы запускаете профилировщик вместо того, чтобы рассчитывать на свою догадку? – liori

+0

Это python2, thx. – antonio

+0

Итак, теперь вы должны использовать профилировщик (например, здесь: http://stackoverflow.com/questions/3927628/how-can-i-profile-python-code-line-by-line), чтобы выяснить, какая конкретная линия занимает самое время. – liori

ответ

1

Это было окончательное решение, слишком поздно для публикации здесь, может быть ... Но я думаю, что, возможно, это полезно для кого-то.

# CRC16EVAL CRC-CCITT check with the polynomial: x^16+x^12+x^5+1 
def crc16eval(D): 
    crchi = 255 
    crclo = 255 

    crc16htab = [0, 16, 32, 48, 64, 80, 96, 112, 129, 145, 161, 177, 193, 209, 225, 241, 18, 2, 50, 34, 82, 66, 114, 98, 147, 131, 179, 163, 211, 195, 243, 227, 36, 52, 4, 20, 100, 116, 68, 84, 165, 181, 133, 149, 229, 245, 197, 213, 54, 38, 22, 6, 118, 102, 86, 70, 183, 167, 151, 135, 247, 231, 215, 199, 72, 88, 104, 120, 8, 24, 40, 56, 201, 217, 233, 249, 137, 153, 169, 185, 90, 74, 122, 106, 26, 10, 58, 42, 219, 203, 251, 235, 155, 139, 187, 171, 108, 124, 76, 92, 44, 60, 12, 28, 237, 253, 205, 221, 173, 189, 141, 157, 126, 110, 94, 78, 62, 46, 30, 14, 255, 239, 223, 207, 191, 175, 159, 143, 145, 129, 177, 161, 209, 193, 241, 225, 16, 0, 48, 32, 80, 64, 112, 96, 131, 147, 163, 179, 195, 211, 227, 243, 2, 18, 34, 50, 66, 82, 98, 114, 181, 165, 149, 133, 245, 229, 213, 197, 52, 36, 20, 4, 116, 100, 84, 68, 167, 183, 135, 151, 231, 247, 199, 215, 38, 54, 6, 22, 102, 118, 70, 86, 217, 201, 249, 233, 153, 137, 185, 169, 88, 72, 120, 104, 24, 8, 56, 40, 203, 219, 235, 251, 139, 155, 171, 187, 74, 90, 106, 122, 10, 26, 42, 58, 253, 237, 221, 205, 189, 173, 157, 141, 124, 108, 92, 76, 60, 44, 28, 12, 239, 255, 207, 223, 175, 191, 143, 159, 110, 126, 78, 94, 46, 62, 14, 30] 

    crc16ltab = [0, 33, 66, 99, 132, 165, 198, 231, 8, 41, 74, 107, 140, 173, 206, 239, 49, 16, 115, 82, 181, 148, 247, 214, 57, 24, 123, 90, 189, 156, 255, 222, 98, 67, 32, 1, 230, 199, 164, 133, 106, 75, 40, 9, 238, 207, 172, 141, 83, 114, 17, 48, 215, 246, 149, 180, 91, 122, 25, 56, 223, 254, 157, 188, 196, 229, 134, 167, 64, 97, 2, 35, 204, 237, 142, 175, 72, 105, 10, 43, 245, 212, 183, 150, 113, 80, 51, 18, 253, 220, 191, 158, 121, 88, 59, 26, 166, 135, 228, 197, 34, 3, 96, 65, 174, 143, 236, 205, 42, 11, 104, 73, 151, 182, 213, 244, 19, 50, 81, 112, 159, 190, 221, 252, 27, 58, 89, 120, 136, 169, 202, 235, 12, 45, 78, 111, 128, 161, 194, 227, 4, 37, 70, 103, 185, 152, 251, 218, 61, 28, 127, 94, 177, 144, 243, 210, 53, 20, 119, 86, 234, 203, 168, 137, 110, 79, 44, 13, 226, 195, 160, 129, 102, 71, 36, 5, 219, 250, 153, 184, 95, 126, 29, 60, 211, 242, 145, 176, 87, 118, 21, 52, 76, 109, 14, 47, 200, 233, 138, 171, 68, 101, 6, 39, 192, 225, 130, 163, 125, 92, 63, 30, 249, 216, 187, 154, 117, 84, 55, 22, 241, 208, 179, 146, 46, 15, 108, 77, 170, 139, 232, 201, 38, 7, 100, 69, 162, 131, 224, 193, 31, 62, 93, 124, 155, 186, 217, 248, 23, 54, 85, 116, 147, 178, 209, 240] 

    for k in range(len(D)): 
     ix = crchi^D[k] 
     crchi = crclo^crc16htab[ix] 
     crclo = crc16ltab[ix] 

    return crchi*256+crclo 

Антонио.

1

Если вам нужно вычислить только CRC16 (только результат, а не код), вы можете использовать PyCRC или CRC-16.

+0

Я пробовал использовать эти пакеты, но pycrc использует другую полиномиальную функцию. Мне нужен полином x^16 + x^12 + x^5 + 1 И этот пакет использует: x^16 + x^15 + x^10 + x^3 многочлен – antonio

2

Я рекомендую прочитать Ross Williams, A painless guide to CRC algorigthms, который научит вас всему, что вы когда-либо хотели узнать о CRC, и о том, как быстро их вычислить.

Описание: Преобразование алгоритма CCITT CRC, используемого в ядре linux. Это может быть или не быть таким же, как то, что вы вычисляете как (если вы прочтете выше), вы поймете, что при вычислении CRC существует довольно много регуляторов.

# This mysterious table is just the CRC of each possible byte. It can be 
# computed using the standard bit-at-a-time methods. The polynomial can 
# be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. 
# Add the implicit x^16, and you have the standard CRC-CCITT. 
# From linux kernel lib/crc-ccitt.c 

_crc_table = (
     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 
) 

def update_crc(data, crc, table=_crc_table): 
    """ 
    Add a byte to the crc calculation 
    """ 
    return (crc >> 8)^table[(crc^data) & 0xff] 

def calculate_crc(data, crc=0xFFFF, table=_crc_table): 
    """ 
    Calculates the CRC for the data string passed in 
    """ 
    for c in data: 
     crc = update_crc(ord(c), crc, table) 
    return crc 

print "%04X" % calculate_crc("Hello") 
Смежные вопросы