2012-11-03 21 views
7

में कनवर्ट करें मैं वर्तमान में एक परियोजना पर काम कर रहा हूं, जिसमें एक एम्बेडेड सिस्टम रेडियो के माध्यम से एक पीसी को डेटा भेज रहा है। पैकेट अंत में एक CRC16 चेकसम मिलता है और यह इस एल्गोरिथ्म आधार पर की जाती है:सी सीआरसी 16 को जावा सीआरसी 16

uint16_t crc16 (const uint8_t * buffer, uint32_t size) { 
    uint16_t crc = 0xFFFF; 

    if (buffer && size) 
     while (size--) 
     { 
      crc = (crc >> 8) | (crc << 8); 
      crc ^= *buffer++; 
      crc ^= ((unsigned char) crc) >> 4; 
      crc ^= crc << 12; 
      crc ^= (crc & 0xFF) << 5; 
     } 

    return crc; 
} 

अब मैं जावा में एक बराबर रहा हूँ। http://introcs.cs.princeton.edu/java/51data/CRC16CCITT.java.html

public class CRC16CCITT { 

    public static void main(String[] args) { 
     int crc = 0xFFFF;   // initial value 
     int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) 

     // byte[] testBytes = "123456789".getBytes("ASCII"); 

     byte[] bytes = args[0].getBytes(); 

     for (byte b : bytes) { 
      for (int i = 0; i < 8; i++) { 
       boolean bit = ((b >> (7-i) & 1) == 1); 
       boolean c15 = ((crc >> 15 & 1) == 1); 
       crc <<= 1; 
       if (c15^bit) crc ^= polynomial; 
      } 
     } 

     crc &= 0xffff; 
     System.out.println("CRC16-CCITT = " + Integer.toHexString(crc)); 
    } 

} 

लेकिन मेरी सी कोड के साथ यह does not काम: मैं पहले से ही यहाँ एक अच्छा एक मिल गया।

क्या कोई सी और जावा समकक्ष एल्गोरिदम के लिए अनुकूलन या समाधान प्रदान करने में सक्षम है? धन्यवाद!

+0

क्यों आप हर यात्रा पर 'सीआरसी =' सेट कर रहे हैं के रूप में इस प्रत्येक मान लेकिन पिछले अनदेखी रूप में ही है:

यह मेरा कार्यान्वयन है। –

+0

तो मुझे तब क्या लिखना है? सीआरसी^=? मैंने बस एक ओपन सोर्स प्रोजेक्ट से कोड कॉपी किया है जिनके साथ मैंने काम किया था। – tellob

+0

इस से सीआरसी की गणना करने के बहुत तेज़ तरीके हैं। खोज जारी रखिये। एक टेबल संचालित विधि है। – EJP

उत्तर

21

इस मामले में जावा और सी के बीच बड़ा अंतर यह तथ्य है कि आप हस्ताक्षरित संख्याओं का उपयोग करते हैं और जावा ने केवल संख्याओं पर हस्ताक्षर किए हैं। जबकि आप हस्ताक्षरित संख्याओं के साथ एक ही एल्गोरिदम लागू कर सकते हैं, आपको इस बात से अवगत होना चाहिए कि शिफ्ट ऑपरेशन पर साइन बिट ले जाया गया है, जिसके लिए अतिरिक्त "और" की आवश्यकता है।

static int crc16(final byte[] buffer) { 
    int crc = 0xFFFF; 

    for (int j = 0; j < buffer.length ; j++) { 
     crc = ((crc >>> 8) | (crc << 8))& 0xffff; 
     crc ^= (buffer[j] & 0xff);//byte to int, trunc sign 
     crc ^= ((crc & 0xff) >> 4); 
     crc ^= (crc << 12) & 0xffff; 
     crc ^= ((crc & 0xFF) << 5) & 0xffff; 
    } 
    crc &= 0xffff; 
    return crc; 

} 
+0

क्या यह मेरे द्वारा पोस्ट किए गए सी कोड के कार्यान्वयन है? – tellob

+0

यह सीआरसी फ़ंक्शन है जो मैं अपने कोड में उपयोग करता हूं - बशर्ते प्रारंभिक मान एक ही (0xFFFF) है और बहुपद एक ही है (0x1021) उन्हें सटीक परिणाम देना चाहिए। – thedayofcondor

+0

मुझे जो पैकेज मिलता है वह है: 1 20 0 -30 -1 72 -31 -110 64 1 0 2 0 3 0 4 0 5 0 125 -7। 21 बाइट्स पैकेज सीआरसी -1667 है। मुझे आखिरी बाइट के क्रम को बदलना पड़ा। जब मैं आपके एल्गोरिदम सीआरसी का उपयोग करता हूं तो मुझे 3377 बचाता है। – tellob