簡體   English   中英

CRC16 CCITT Java 實現

[英]CRC16 CCITT Java implementation

有一個 function 寫在 C 中,計算 CRC16 CCITT。 它有助於從 RFID 閱讀器讀取數據 - 並且基本上可以正常工作。 我想在 Java 中寫一個 function 來做類似的事情。 我嘗試了在線轉換器頁面來執行此操作,但我得到的代碼是垃圾。 您能否看一下這個並建議為什么 Java 代碼應該執行相同的操作會生成不同的 crc? 請找到隨附的原始 C function:

void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
    int i, byte;
    unsigned short C;

    *CRC = 0;
    for (byte = 1; byte <= Bytes; byte++, Data++)
    {
        C = ((*CRC >> 8) ^ *Data) << 8;
        for (i = 0; i < 8; i++)
        {
            if (C & 0x8000)
                C = (C << 1) ^ 0x1021;
            else
                C = C << 1;
        }
        *CRC = C ^ (*CRC << 8);
    }
}

這是用 JAVA 編寫的不同 CRC function 應該計算相同的校驗和,但它沒有:

public static int CRC16_CCITT_Test(byte[] buffer) {
     int wCRCin = 0x0000; 
     int wCPoly = 0x1021; 
     for (byte b : buffer) {
         for (int i = 0; i < 8; i++) {
             boolean bit = ((b >> (7 - i) & 1) == 1);
             boolean c15 = ((wCRCin >> 15 & 1) == 1);
             wCRCin <<= 1;
             if (c15 ^ bit)
                 wCRCin ^= wCPoly;
         }
     }
     wCRCin &= 0xffff;
     return wCRCin;
    }

When I try calculating 0,2,3 numbers in both functions I got different results: for C function it is (DEC): 22017 for JAVA function it is (DEC): 28888

好的。 我將 C 轉換為 Java 代碼並使其部分工作。

public static int CRC16_Test(byte[] data,  byte bytes) {
            int dataIndex = 0;
            short c;
            short [] crc= {0};

            crc[0] = (short)0;
            for(int j = 1; j <= Byte.toUnsignedInt(bytes); j++, dataIndex++) {
                c = (short)((Short.toUnsignedInt(crc[0]) >> 8 ^ Byte.toUnsignedInt(data[dataIndex])) << 8);
                for(int i = 0; i < 8; i++) {
                    if((Short.toUnsignedInt(c) & 0x8000) != 0) {
                        c = (short)(Short.toUnsignedInt(c) << 1 ^ 0x1021);
                    } else {
                        c = (short)(Short.toUnsignedInt(c) << 1);
                    }
                }
                crc[0] = (short)(Short.toUnsignedInt(c) ^ Short.toUnsignedInt(crc[0]) << 8);
            }
        return crc[0];
        }

它具有與C代碼為0,2,3數字相同的CRC值,但對於數字255,216,216,228 Z0D61F8370CAD1D41D41D41D412F80B84D1212121212179D17ND19D19D19D19D19D19ND19D19ND19D19ND19ND19D19D19ND19ND19ND.ND19ND.RC.

好的。 最后感謝您的指點,我得到了這個工作。 所需的最后更改是將'return crc [0]'更改為:

return (int) crc[0] & 0xffff;

...並且它有效...非常感謝所有人:)

沒有任何錯誤。 對於 16 位值,–4537 表示為與 60999 完全相同的 16 位。 如果您希望您的例程返回正版本,請轉換為int (即 32 位)並執行& 0xffff

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM