2016-08-31 10 views
1

私はCRC16 DNPをこの実装から(拘束されたデバイスから)運が無ければ翻訳しようとしています。CRC16 CRC16 DNPチェックサムアルゴリズム(Java)

uint16_t Crc16Dnp_computeBuffer(uint8_t const (* const message), uint16_t const ui16Size){ 
uint16_t remainder = INITIAL_REMAINDER; 
uint16_t data; 
uint8_t byte; 

// assert_panic message != 0U 

/* 
* Divide the message by the polynomial, a byte at a time. 
*/ 
for (byte = 0; byte < ui16Size; ++byte) { 
    data = reflect_byte(message[byte])^(remainder >> (16U - 8U)); 
    remainder = crcTable[data]^(remainder << 8U); 
} 

/* 
* The final remainder is the CRC. 
*/ 
return (reflect_word(remainder)^FINAL_XOR_VALUE); 
} 

事前に計算テーブルと定数:

static const uint16_t crcTable[256] = 
{ 0x0000, 0x3D65, 0x7ACA, 0x47AF, 0xF594, 0xC8F1, 0x8F5E, 0xB23B, 0xD64D,  0xEB28, 0xAC87, 0x91E2, 0x23D9, 0x1EBC, 
0x5913, 0x6476, 0x91FF, 0xAC9A, 0xEB35, 0xD650, 0x646B, 0x590E, 0x1EA1, 0x23C4, 0x47B2, 0x7AD7, 0x3D78, 0x001D, 
0xB226, 0x8F43, 0xC8EC, 0xF589, 0x1E9B, 0x23FE, 0x6451, 0x5934, 0xEB0F, 0xD66A, 0x91C5, 0xACA0, 0xC8D6, 0xF5B3, 
0xB21C, 0x8F79, 0x3D42, 0x0027, 0x4788, 0x7AED, 0x8F64, 0xB201, 0xF5AE, 0xC8CB, 0x7AF0, 0x4795, 0x003A, 0x3D5F, 
0x5929, 0x644C, 0x23E3, 0x1E86, 0xACBD, 0x91D8, 0xD677, 0xEB12, 0x3D36, 0x0053, 0x47FC, 0x7A99, 0xC8A2, 0xF5C7, 
0xB268, 0x8F0D, 0xEB7B, 0xD61E, 0x91B1, 0xACD4, 0x1EEF, 0x238A, 0x6425, 0x5940, 0xACC9, 0x91AC, 0xD603, 0xEB66, 
0x595D, 0x6438, 0x2397, 0x1EF2, 0x7A84, 0x47E1, 0x004E, 0x3D2B, 0x8F10, 0xB275, 0xF5DA, 0xC8BF, 0x23AD, 0x1EC8, 
0x5967, 0x6402, 0xD639, 0xEB5C, 0xACF3, 0x9196, 0xF5E0, 0xC885, 0x8F2A, 0xB24F, 0x0074, 0x3D11, 0x7ABE, 0x47DB, 
0xB252, 0x8F37, 0xC898, 0xF5FD, 0x47C6, 0x7AA3, 0x3D0C, 0x0069, 0x641F, 0x597A, 0x1ED5, 0x23B0, 0x918B, 0xACEE, 
0xEB41, 0xD624, 0x7A6C, 0x4709, 0x00A6, 0x3DC3, 0x8FF8, 0xB29D, 0xF532, 0xC857, 0xAC21, 0x9144, 0xD6EB, 0xEB8E, 
0x59B5, 0x64D0, 0x237F, 0x1E1A, 0xEB93, 0xD6F6, 0x9159, 0xAC3C, 0x1E07, 0x2362, 0x64CD, 0x59A8, 0x3DDE, 0x00BB, 
0x4714, 0x7A71, 0xC84A, 0xF52F, 0xB280, 0x8FE5, 0x64F7, 0x5992, 0x1E3D, 0x2358, 0x9163, 0xAC06, 0xEBA9, 0xD6CC, 
0xB2BA, 0x8FDF, 0xC870, 0xF515, 0x472E, 0x7A4B, 0x3DE4, 0x0081, 0xF508, 0xC86D, 0x8FC2, 0xB2A7, 0x009C, 0x3DF9, 
0x7A56, 0x4733, 0x2345, 0x1E20, 0x598F, 0x64EA, 0xD6D1, 0xEBB4, 0xAC1B, 0x917E, 0x475A, 0x7A3F, 0x3D90, 0x00F5, 
0xB2CE, 0x8FAB, 0xC804, 0xF561, 0x9117, 0xAC72, 0xEBDD, 0xD6B8, 0x6483, 0x59E6, 0x1E49, 0x232C, 0xD6A5, 0xEBC0, 
0xAC6F, 0x910A, 0x2331, 0x1E54, 0x59FB, 0x649E, 0x00E8, 0x3D8D, 0x7A22, 0x4747, 0xF57C, 0xC819, 0x8FB6, 0xB2D3, 
0x59C1, 0x64A4, 0x230B, 0x1E6E, 0xAC55, 0x9130, 0xD69F, 0xEBFA, 0x8F8C, 0xB2E9, 0xF546, 0xC823, 0x7A18, 0x477D, 
0x00D2, 0x3DB7, 0xC83E, 0xF55B, 0xB2F4, 0x8F91, 0x3DAA, 0x00CF, 0x4760, 0x7A05, 0x1E73, 0x2316, 0x64B9, 0x59DC, 
0xEBE7, 0xD682, 0x912D, 0xAC48 
}; 

#define POLYNOMIAL   (uint16_t)0x13D65U 
#define INITIAL_REMAINDER (uint16_t)0x0000U 
#define FINAL_XOR_VALUE  (uint16_t)0xFFFFU 

この場合reflect_xxメソッドは何もせずにデータを返します。 私はこれを翻訳しようとしているが、Javaの符号なしの問題... 私の現在のコードで立ち往生されています:

public static short crc16dnpComputeBuffer_U(byte[] buf) { 
    int remainder = 0x0000; 
    int data; 
    /* 
* Divide the message by the polynomial, a byte at a time. 
    */ 
    for (int i = 0; i < buf.length; i++) { 
     data = (buf[i]^(remainder) >>> ((16) - (8))) & 0xffff; 
     System.out.println(data); 
     remainder = crcTable[data]^(remainder << 8) & 0xffff; 
    } 
    /* 
* The final remainder is the CRC. 
    */ 
    return (short) (remainder^(short) 0xFFFF); 
} 

データインデックスが配列の長さ以上になる。このアプローチを使用します。 CRCがE44Bある

08AA0001B6340020040B1B1DE5000000000000000000287D0100000000003A7D0100000000003D7D010000000000437D0100000000002E7D0100000000003F7D010000000000367D0100000000003C7D0100000000003E7D0100000000002B7D0100000000003B7D010000000000397D010000000000427D010000000000357D0100000000003F7D010000000000317D0100000000003C7D010000000000387D010000000000467D010000000000 

:このヘクスで表されるバイトデータの例として

私が間違っていることに関するヒントはありますか?

ありがとうございます!

UPDATE:あなたの助けを借りて、私はついにそれを得た:

public static short crc16dnpComputeBuffer_U(byte[] buf) { 
    int remainder = 0x0000; 
    int data; 
    /* 
* Divide the message by the polynomial, a byte at a time. 
    */ 
    for (int i = 0; i < buf.length; i++) { 
     data = (buf[i]^remainder >>> (16) - (8)) & 0xff; 
     remainder = crcTable[data]^(remainder << 8); 
    } 
    /* 
* The final remainder is the CRC. 
    */ 
    return (short) (remainder^(short) 0xFFFF); 
} 
+0

私はここ数ヶ月前によく助けてくれました http://stackoverflow.com/questions/25934003/how-to-implement-crc-16-dnp-using-c – MaglioniLorenzo

+0

ところで、私は'^'、 '&'、 '>>>'演算子の使用については、それらの優先順位が明白でないため、かっこを使用することをお勧めします。どちらが最初に適用されたのかを判断するために、Java優先順位テーブルを調べなければなりませんでした。 –

+0

両方のコメントありがとう! – Eingel

答えて

1

shortbyteすべてが署名されているので、符号拡張Javaでintにあります。 dataの式は、& 0xffの範囲で値0..255を取得する必要があります。

また、戻り値は約半分の時間になりますが、これは実際にはCの実装で正の符号なしとして返される16ビットの値と同じであることにも注意してください(内部& 0xfffは必要ありません)。値。

+0

''0xff'''を指してくれてありがとう。 – Eingel

関連する問題