2012-11-03 55 views
7

Tôi hiện đang làm việc trên một dự án, có một hệ thống nhúng gửi dữ liệu đến PC qua radio. Các gói nhận được một checksum crc16 ở cuối và nó được tính toán dựa trên thuật toán này:Chuyển đổi C CRC16 sang Java CRC16

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

Bây giờ tôi đang tìm kiếm một tương đương trong Java. Tôi đã tìm thấy một trong những tốt ở đây: 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)); 
    } 

} 

Nhưng công việc doesnt này với Mã C của tôi.

Có ai có thể cung cấp khả năng thích ứng hoặc giải pháp cho thuật toán tương đương C và Java không? Cảm ơn bạn!

+0

Tại sao các bạn cách thiết lập 'crc = 'trên mỗi iteration vì đây là giống như bỏ qua tất cả các giá trị nhưng cuối cùng. –

+0

Vậy tôi phải viết gì? crc^=? Tôi vừa sao chép mã từ một dự án mã nguồn mở mà tôi đã làm việc cùng. – tellob

+0

Có nhiều cách để tính toán CRcs nhanh hơn nhiều. Tiếp tục tìm kiếm. Có một phương pháp điều khiển bảng. – EJP

Trả lời

21

Sự khác biệt chính giữa java và c trong trường hợp này là sự kiện trong c bạn sử dụng số chưa ký và java chỉ có số đã ký. Trong khi bạn có thể thực hiện cùng một thuật toán với các con số đã ký, bạn phải nhận thức được thực tế bit dấu được thực hiện trên các phép toán thay đổi, yêu cầu thêm "và".

Đây là triển khai thực hiện của tôi:

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

Đây có phải là việc triển khai mã c mà tôi đã đăng không? – tellob

+0

Đây là hàm CRC tôi sử dụng trong mã của tôi - miễn là giá trị ban đầu là giống nhau (0xFFFF) và đa thức là giống nhau (0x1021) chúng nên cho kết quả tương tự. – thedayofcondor

+0

Gói tôi nhận được là: 1 20 0 -30 -1 72 -31 -110 64 1 0 2 0 3 0 4 0 5 0 125 -7. 21 byte. Các gói crc sau đó là -1667. Tôi phải thay đổi thứ tự của byte cuối cùng thành byte. Khi tôi sử dụng thuật toán crc của bạn mang lại cho tôi 3377. – tellob