2014-03-06 52 views
0

我目前正在尋找如何確定從機器產生的CRC到PC(反之亦然)。 設備正在使用串行通信或RS232電纜進行通信。CRC反向工程師(Checksum從機器/ PC)

I do only have data to be able for us to create a program to be used for both devices. 

The data given was from my boss and the program was corrupted. So we are trying for it to work out. 

I hope everyone can help. 

Thanks :) 
+0

您應該至少考慮一下,指定將_think_用作crc計算的src數據。您還應該查看數據的格式 - 它不完全一致或清晰。例如什麼是'0D 0A'?是5 ascii charcaters,還是2個字符,其值以十六進制表示?請注意,在你甚至可以開始猜測使用的CRC算法和使用的種子值之前,你必須弄清楚你正在計算CRC的值。也就是說,它是發送的任何二進制數據的CRC,是整行的CRC等,等等。 – enhzflep

+0

對於簡短的信息,我很抱歉,是的字符串是「字符/字符串,而十六進制數字是ASCII表格(例如06是ACK),我們無法預測它是整行還是特定字符。 – user3387293

+0

0D 0A是回車和換行ascii .. – user3387293

回答

2

用於在協議CRC計算的序列是ASCII字符串

  • 從第一打印字符(從REQ如「R」)開始
  • 直到和包括該'1E'在計算中。
  • 這是一個兒童權利委員會根據我們CRC calculator

    CRC以下規格:16,1021,0000,0000,不,不

這意味着:

CRC width: 16 bit (of course) 
polynomial: 1021 HEX (truncated CRC polynomial) 
init value: 0000 
final Xor applied: 0000 
reflectedInput: No 
reflectedOutput: No` 

(如果'初始值'是FFFF,它將是一個「CCITT指定的16位寬的CRC」)。

另請參閱Docklight CRC glossaryBoost CRC library關於CRC術語的含義以及示例代碼。

我所做的是編寫一個小腳本,在第一個簡單的「REQ = INI」命令的不同部分上嘗試使用流行的16位CRC,並查看我是否總計4255。但我並不想全力嘗試各種各樣的多項式,而是假定它可能只是一個奇怪的/有缺陷的已知標準實現,而且確實成功地通過了CRC-CCITT的變體。

繼承人是有些慢&容易C代碼(不是基於表!)來計算CRC的種種:

// Generic, not table-based CRC calculation 
// Based on and credits to the following: 
// CRC tester v1.3 written on 4th of February 2003 by Sven Reifegerste (zorc/reflex) 

unsigned long reflect (unsigned long crc, int bitnum) { 

    // reflects the lower 'bitnum' bits of 'crc' 
    unsigned long i, j=1, crcout=0; 
    for (i=(unsigned long)1<<(bitnum-1); i; i>>=1) { 
     if (crc & i) crcout|=j; 
     j<<= 1; 
    } 
    return (crcout); 
}  

calcCRC(
    const int width, const unsigned long polynominal, const unsigned long initialRemainder, 
    const unsigned long finalXOR, const int reflectedInput, const int reflectedOutput, 
    const unsigned char message[], const long startIndex, const long endIndex) 
{ 
    // Ensure the width is in range: 1-32 bits 
    assert(width >= 1 && width <= 32); 
    // some constant parameters used 
    const bool b_refInput = (reflectedInput > 0); 
    const bool b_refOutput = (reflectedOutput > 0); 
    const unsigned long crcmask = ((((unsigned long)1<<(width-1))-1)<<1)|1; 
    const unsigned long crchighbit = (unsigned long)1<<(width-1); 

    unsigned long j, c, bit; 
    unsigned long crc = initialRemainder; 

    for (long msgIndex = startIndex; msgIndex <= endIndex; ++msgIndex) { 
     c = (unsigned long)message[msgIndex]; 
     if (b_refInput) c = reflect(c, 8); 
     for (j=0x80; j; j>>=1) { 
      bit = crc & crchighbit; 
      crc<<= 1; 
      if (c & j) bit^= crchighbit; 
      if (bit) crc^= polynominal; 
     } 
    } 
    if (b_refOutput) crc=reflect(crc, width); 
    crc^= finalXOR; 
    crc&= crcmask; 
    return(crc); 
} 

有了這個代碼,並在上述的CRC規格,我已經能夠重新計算以下三個樣品的CRC:

10.03.2014 22:20:57.109 [TX] - REQ=INI<CR><LF> 
<RS>CRC=4255<CR><LF> 
<GS> 
10.03.2014 22:20:57.731 [TX] - ANS=INI<CR><LF> 
STATUS=0<CR><LF> 
<RS>CRC=57654<CR><LF> 
<GS> 
10.03.2014 22:20:59.323 [TX] - ANS=INI<CR><LF> 
STATUS=0<CR><LF> 
MID="CTL1"<CR><LF> 
DEF="DTLREQ";1025<CR><LF> 
INFO=0<CR><LF> 
<RS>CRC=1683<CR><LF> 
<GS> 

我失敗了非常複雜的一個與DEF=部分 - 可能沒有正確認識的字符序列。

我用扭轉Docklight腳本工程師這樣的:

Sub crcReverseEngineer() 
    Dim crctypes(7) 

    crctypes(0) = "CRC:16,1021,FFFF,0000" ' CCITT 
    crctypes(1) = "CRC:16,8005,0000,0000" ' CRC-16 
    crctypes(2) = "CRC:16,8005,FFFF,0000" ' CRC-MODBUS 

    ' lets try also some nonstandard variations with different init and final Xor, but stick 
    ' to the known two polynoms. 

    crctypes(3) = "CRC:16,1021,FFFF,FFFF" 
    crctypes(4) = "CRC:16,1021,0000,FFFF" 
    crctypes(5) = "CRC:16,1021,0000,0000" 

    crctypes(6) = "CRC:16,8005,FFFF,FFFF" 
    crctypes(7) = "CRC:16,8005,FFFF,0000" 

    crcString = "06 1C 52 45 51 3D 49 4E 49 0D 0A 1E 43 52 43 3D 30 30 30 30 0D 0A 1D" 

    For reflectedInOrOut = 0 To 3 
     For cType = 0 To 7 
      crcSpec = crctypes(cType) & "," & IIf(reflectedInOrOut Mod 2 = 1, "Yes", "No") & "," & IIf(reflectedInOrOut > 1, "Yes", "No") 
      For cStart = 1 To 3 
       For cEnd = 9 To (Len(crcString) + 1)/3 
        subDataString = Mid(crcString, (cStart - 1) * 3 + 1, (cEnd - cStart + 1) * 3) 
        result = DL.CalcChecksum(crcSpec, subDataString, "H") 
        resultInt = CLng("&h" + Left(result, 2)) * 256 + CLng("&h" + Right(result, 2)) 
        If resultInt = 4255 Then 
         DL.AddComment "Found it!" 
         DL.AddComment "sequence: " & subDataString 
         DL.AddComment "CRC spec: " & crcSpec 
         DL.AddComment "CRC result: " & result & " (Integer = " & resultInt & ")" 
         Exit Sub 
        End If 
       Next 
      Next 
     Next 
    Next 
End Sub 

Public Function IIf(blnExpression, vTrueResult, vFalseResult) 
    If blnExpression Then 
    IIf = vTrueResult 
    Else 
    IIf = vFalseResult 
    End If 
End Function 

希望這有助於我很樂意爲您提供額外的信息或澄清細節。

+0

很好的描述你的方法和分析。我希望我可以多點讚賞。 –

+0

@OliverHeggelbacher這真是太神奇了......我不知道會有串口監視器和腳本程序。請問我是否需要該程序的完整許可證才能測試您提供的示例代碼。 – user3387293

+0

@OliverHeggelbacher - 關於「DEF =部件」,該數字對於機器上的每次登錄都是遞增的。但個人電腦可以確定下一個要發送給機器的號碼。 – user3387293