2016-08-31 1 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 방법은 아무것도하지 않고 데이터를 반환합니다. 데이터 인덱스가 배열의 길이를 초과 할 때이 방법을 사용

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

: 나는 내 현재 코드 ...이 번역하려고하지만, 자바 서명되지 않은 문제에 붙어있다.

이 진수로 나타낸 바이트 데이터로 예 :

08AA0001B6340020040B1B1DE5000000000000000000287D0100000000003A7D0100000000003D7D010000000000437D0100000000002E7D0100000000003F7D010000000000367D0100000000003C7D0100000000003E7D0100000000002B7D0100000000003B7D010000000000397D010000000000427D010000000000357D0100000000003F7D010000000000317D0100000000003C7D010000000000387D010000000000467D010000000000 

CRC는 E44B이다.

내가 잘못하고있는 것에 대한 힌트가 있습니까?

감사합니다.

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는, 부호 확장 자바 int에 있습니다. data의 표현식을 & 0xff으로 설정하여 0..255 범위의 값을 가져와야합니다. (& 0xfff은 필요하지 않습니다.)

반환 값은 대략 절반으로 음수가됩니다. 실제로는 C 구현에서 양수 부호없는 값으로 반환되는 것과 동일한 16 비트 값입니다. 값.

+0

'''0xff'''을 지적 해 주셔서 감사합니다. – Eingel