Home AMX User Forum NetLinx Studio

Example for CRC16 ?

Hello

Does anyone has a working example / function how to build CRC16-checksums?

Thanx :-)

Comments

  • YuriyYuriy Posts: 20
    Example for CRC16 by AMX

    Let?s look a t an example of a Cyclical Redundency Checking (CRC) CheckSum:

    DEFINE_CALL 'CRC CALC' (LENGTH,STRING[30],H_CRC,L_CRC)
    LOCAL_VAR COUNT1 COUNT2 CRC
    {
    CRC = 0
    COUNT1 = 1
    WHILE ( COUNT1 <= LENGTH )
    {
    COUNT2 = 1
    CRC = CRC BXOR (STRING[COUNT1] * 256)
    WHILE (COUNT2 < 9)
    {
    IF (CRC BAND $8000)
    CRC = (CRC *2) BXOR $1021
    ELSE
    CRC = CRC * 2
    COUNT2 = COUNT2 + 1
    }
    COUNT1 = COUNT1 + 1
    }
    H_CRC = CRC/256
    L_CRC = CRC BAND 255
    }

    Here a 16 bit CheckSum is represented as the High and Low bytes. The first byte is multiplied by 256 and then BXORed with 0. The result is BANDed with $8000. If there is a 1 in the 16th bit the result is multiplied by 2 then BXORed with $1021, then the result is run through that process 7 more times. Then the second byte is BXORed with that result and that result is processed 8 times. This is repeated until all bits are done. Then we divide the 16 bits into two values, the High and Low CheckSum Bytes. The High by dividing and the Low by BANDing.

    This example I found in paper "Bitwise Operations".
  • kphlightkphlight Posts: 10
    Lookup table == faster code

    Edited: Use code below
  • kphlightkphlight Posts: 10
    Untested

    Edited: Use code below
  • Something is wrong with the code from "kphlight"

    I testet the code from kphlight because i have very much strings to transmit & calculate.
    It looks like the fastest way....

    But i get some Errors:

    Ref Error ^CRC16_LOOKUP Index 0 Line=135
    DoNumberExpression - Error 2 Tk=0x2012 Line=135
    GetNumber - Error 1 Tk=0x0000
    RunCode - Address Mismatch 0x4050 0x000704 0x000706

    The problem ist, that the (t = (crc16retVal / 16) BXOR crcString ) returns "516" or "0"

    Is the initializer with $FFFF correct???


    Greetings & thanx fo help:


    Lukas
  • kphlightkphlight Posts: 10
    Fun stuff
    define_variable //(or define_constant)
    
    volatile integer g_pCRC16Tab[] = {
        $0000, $C0C1, $C181, $0140, $C301, $03C0, $0280, $C241,
        $C601, $06C0, $0780, $C741, $0500, $C5C1, $C481, $0440,
        $CC01, $0CC0, $0D80, $CD41, $0F00, $CFC1, $CE81, $0E40,
        $0A00, $CAC1, $CB81, $0B40, $C901, $09C0, $0880, $C841,
        $D801, $18C0, $1980, $D941, $1B00, $DBC1, $DA81, $1A40,
        $1E00, $DEC1, $DF81, $1F40, $DD01, $1DC0, $1C80, $DC41,
        $1400, $D4C1, $D581, $1540, $D701, $17C0, $1680, $D641,
        $D201, $12C0, $1380, $D341, $1100, $D1C1, $D081, $1040,
        $F001, $30C0, $3180, $F141, $3300, $F3C1, $F281, $3240,
        $3600, $F6C1, $F781, $3740, $F501, $35C0, $3480, $F441,
        $3C00, $FCC1, $FD81, $3D40, $FF01, $3FC0, $3E80, $FE41,
        $FA01, $3AC0, $3B80, $FB41, $3900, $F9C1, $F881, $3840,
        $2800, $E8C1, $E981, $2940, $EB01, $2BC0, $2A80, $EA41,
        $EE01, $2EC0, $2F80, $EF41, $2D00, $EDC1, $EC81, $2C40,
        $E401, $24C0, $2580, $E541, $2700, $E7C1, $E681, $2640,
        $2200, $E2C1, $E381, $2340, $E101, $21C0, $2080, $E041,
        $A001, $60C0, $6180, $A141, $6300, $A3C1, $A281, $6240,
        $6600, $A6C1, $A781, $6740, $A501, $65C0, $6480, $A441,
        $6C00, $ACC1, $AD81, $6D40, $AF01, $6FC0, $6E80, $AE41,
        $AA01, $6AC0, $6B80, $AB41, $6900, $A9C1, $A881, $6840,
        $7800, $B8C1, $B981, $7940, $BB01, $7BC0, $7A80, $BA41,
        $BE01, $7EC0, $7F80, $BF41, $7D00, $BDC1, $BC81, $7C40,
        $B401, $74C0, $7580, $B541, $7700, $B7C1, $B681, $7640,
        $7200, $B2C1, $B381, $7340, $B101, $71C0, $7080, $B041,
        $5000, $90C1, $9181, $5140, $9301, $53C0, $5280, $9241,
        $9601, $56C0, $5780, $9741, $5500, $95C1, $9481, $5440,
        $9C01, $5CC0, $5D80, $9D41, $5F00, $9FC1, $9E81, $5E40,
        $5A00, $9AC1, $9B81, $5B40, $9901, $59C0, $5880, $9841,
        $8801, $48C0, $4980, $8941, $4B00, $8BC1, $8A81, $4A40,
        $4E00, $8EC1, $8F81, $4F40, $8D01, $4DC0, $4C80, $8C41,
        $4400, $84C1, $8581, $4540, $8701, $47C0, $4680, $8641,
        $8201, $42C0, $4380, $8341, $4100, $81C1, $8081, $4040 }
    
    volatile integer g_pCRC16CcittTable[256] = {
        $0000, $1021, $2042, $3063, $4084, $50a5, $60c6, $70e7,
        $8108, $9129, $a14a, $b16b, $c18c, $d1ad, $e1ce, $f1ef,
        $1231, $0210, $3273, $2252, $52b5, $4294, $72f7, $62d6,
        $9339, $8318, $b37b, $a35a, $d3bd, $c39c, $f3ff, $e3de,
        $2462, $3443, $0420, $1401, $64e6, $74c7, $44a4, $5485,
        $a56a, $b54b, $8528, $9509, $e5ee, $f5cf, $c5ac, $d58d,
        $3653, $2672, $1611, $0630, $76d7, $66f6, $5695, $46b4,
        $b75b, $a77a, $9719, $8738, $f7df, $e7fe, $d79d, $c7bc,
        $48c4, $58e5, $6886, $78a7, $0840, $1861, $2802, $3823,
        $c9cc, $d9ed, $e98e, $f9af, $8948, $9969, $a90a, $b92b,
        $5af5, $4ad4, $7ab7, $6a96, $1a71, $0a50, $3a33, $2a12,
        $dbfd, $cbdc, $fbbf, $eb9e, $9b79, $8b58, $bb3b, $ab1a,
        $6ca6, $7c87, $4ce4, $5cc5, $2c22, $3c03, $0c60, $1c41,
        $edae, $fd8f, $cdec, $ddcd, $ad2a, $bd0b, $8d68, $9d49,
        $7e97, $6eb6, $5ed5, $4ef4, $3e13, $2e32, $1e51, $0e70,
        $ff9f, $efbe, $dfdd, $cffc, $bf1b, $af3a, $9f59, $8f78,
        $9188, $81a9, $b1ca, $a1eb, $d10c, $c12d, $f14e, $e16f,
        $1080, $00a1, $30c2, $20e3, $5004, $4025, $7046, $6067,
        $83b9, $9398, $a3fb, $b3da, $c33d, $d31c, $e37f, $f35e,
        $02b1, $1290, $22f3, $32d2, $4235, $5214, $6277, $7256,
        $b5ea, $a5cb, $95a8, $8589, $f56e, $e54f, $d52c, $c50d,
        $34e2, $24c3, $14a0, $0481, $7466, $6447, $5424, $4405,
        $a7db, $b7fa, $8799, $97b8, $e75f, $f77e, $c71d, $d73c,
        $26d3, $36f2, $0691, $16b0, $6657, $7676, $4615, $5634,
        $d94c, $c96d, $f90e, $e92f, $99c8, $89e9, $b98a, $a9ab,
        $5844, $4865, $7806, $6827, $18c0, $08e1, $3882, $28a3,
        $cb7d, $db5c, $eb3f, $fb1e, $8bf9, $9bd8, $abbb, $bb9a,
        $4a75, $5a54, $6a37, $7a16, $0af1, $1ad0, $2ab3, $3a92,
        $fd2e, $ed0f, $dd6c, $cd4d, $bdaa, $ad8b, $9de8, $8dc9,
        $7c26, $6c07, $5c64, $4c45, $3ca2, $2c83, $1ce0, $0cc1,
        $ef1f, $ff3e, $cf5d, $df7c, $af9b, $bfba, $8fd9, $9ff8,
        $6e17, $7e36, $4e55, $5e74, $2e93, $3eb2, $0ed1, $1ef0
    }
    
    volatile integer g_pCRC16XModemTable[256] = {
        $0000, $17ce, $0fdf, $1811, $1fbe, $0870, $1061, $07af,
        $1f3f, $08f1, $10e0, $072e, $0081, $174f, $0f5e, $1890,
        $1e3d, $09f3, $11e2, $062c, $0183, $164d, $0e5c, $1992,
        $0102, $16cc, $0edd, $1913, $1ebc, $0972, $1163, $06ad,
        $1c39, $0bf7, $13e6, $0428, $0387, $1449, $0c58, $1b96,
        $0306, $14c8, $0cd9, $1b17, $1cb8, $0b76, $1367, $04a9,
        $0204, $15ca, $0ddb, $1a15, $1dba, $0a74, $1265, $05ab,
        $1d3b, $0af5, $12e4, $052a, $0285, $154b, $0d5a, $1a94,
        $1831, $0fff, $17ee, $0020, $078f, $1041, $0850, $1f9e,
        $070e, $10c0, $08d1, $1f1f, $18b0, $0f7e, $176f, $00a1,
        $060c, $11c2, $09d3, $1e1d, $19b2, $0e7c, $166d, $01a3,
        $1933, $0efd, $16ec, $0122, $068d, $1143, $0952, $1e9c,
        $0408, $13c6, $0bd7, $1c19, $1bb6, $0c78, $1469, $03a7,
        $1b37, $0cf9, $14e8, $0326, $0489, $1347, $0b56, $1c98,
        $1a35, $0dfb, $15ea, $0224, $058b, $1245, $0a54, $1d9a,
        $050a, $12c4, $0ad5, $1d1b, $1ab4, $0d7a, $156b, $02a5,
        $1021, $07ef, $1ffe, $0830, $0f9f, $1851, $0040, $178e,
        $0f1e, $18d0, $00c1, $170f, $10a0, $076e, $1f7f, $08b1,
        $0e1c, $19d2, $01c3, $160d, $11a2, $066c, $1e7d, $09b3,
        $1123, $06ed, $1efc, $0932, $0e9d, $1953, $0142, $168c,
        $0c18, $1bd6, $03c7, $1409, $13a6, $0468, $1c79, $0bb7,
        $1327, $04e9, $1cf8, $0b36, $0c99, $1b57, $0346, $1488,
        $1225, $05eb, $1dfa, $0a34, $0d9b, $1a55, $0244, $158a,
        $0d1a, $1ad4, $02c5, $150b, $12a4, $056a, $1d7b, $0ab5,
        $0810, $1fde, $07cf, $1001, $17ae, $0060, $1871, $0fbf,
        $172f, $00e1, $18f0, $0f3e, $0891, $1f5f, $074e, $1080,
        $162d, $01e3, $19f2, $0e3c, $0993, $1e5d, $064c, $1182,
        $0912, $1edc, $06cd, $1103, $16ac, $0162, $1973, $0ebd,
        $1429, $03e7, $1bf6, $0c38, $0b97, $1c59, $0448, $1386,
        $0b16, $1cd8, $04c9, $1307, $14a8, $0366, $1b77, $0cb9,
        $0a14, $1dda, $05cb, $1205, $15aa, $0264, $1a75, $0dbb,
        $152b, $02e5, $1af4, $0d3a, $0a95, $1d5b, $054a, $1284
    }
    
    volatile long g_pCRC32Tab[] = {
        $00000000, $77073096, $EE0E612C, $990951BA,
        $076DC419, $706AF48F, $E963A535, $9E6495A3,
        $0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988,
        $09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91,
        $1DB71064, $6AB020F2, $F3B97148, $84BE41DE,
        $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7,
        $136C9856, $646BA8C0, $FD62F97A, $8A65C9EC,
        $14015C4F, $63066CD9, $FA0F3D63, $8D080DF5,
        $3B6E20C8, $4C69105E, $D56041E4, $A2677172,
        $3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B,
        $35B5A8FA, $42B2986C, $DBBBC9D6, $ACBCF940,
        $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59,
        $26D930AC, $51DE003A, $C8D75180, $BFD06116,
        $21B4F4B5, $56B3C423, $CFBA9599, $B8BDA50F,
        $2802B89E, $5F058808, $C60CD9B2, $B10BE924,
        $2F6F7C87, $58684C11, $C1611DAB, $B6662D3D,
        $76DC4190, $01DB7106, $98D220BC, $EFD5102A,
        $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433,
        $7807C9A2, $0F00F934, $9609A88E, $E10E9818,
        $7F6A0DBB, $086D3D2D, $91646C97, $E6635C01,
        $6B6B51F4, $1C6C6162, $856530D8, $F262004E,
        $6C0695ED, $1B01A57B, $8208F4C1, $F50FC457,
        $65B0D9C6, $12B7E950, $8BBEB8EA, $FCB9887C,
        $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65,
        $4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2,
        $4ADFA541, $3DD895D7, $A4D1C46D, $D3D6F4FB,
        $4369E96A, $346ED9FC, $AD678846, $DA60B8D0,
        $44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9,
        $5005713C, $270241AA, $BE0B1010, $C90C2086,
        $5768B525, $206F85B3, $B966D409, $CE61E49F,
        $5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4,
        $59B33D17, $2EB40D81, $B7BD5C3B, $C0BA6CAD,
        $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A,
        $EAD54739, $9DD277AF, $04DB2615, $73DC1683,
        $E3630B12, $94643B84, $0D6D6A3E, $7A6A5AA8,
        $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1,
        $F00F9344, $8708A3D2, $1E01F268, $6906C2FE,
        $F762575D, $806567CB, $196C3671, $6E6B06E7,
        $FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC,
        $F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5,
        $D6D6A3E8, $A1D1937E, $38D8C2C4, $4FDFF252,
        $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
        $D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60,
        $DF60EFC3, $A867DF55, $316E8EEF, $4669BE79,
        $CB61B38C, $BC66831A, $256FD2A0, $5268E236,
        $CC0C7795, $BB0B4703, $220216B9, $5505262F,
        $C5BA3BBE, $B2BD0B28, $2BB45A92, $5CB36A04,
        $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D,
        $9B64C2B0, $EC63F226, $756AA39C, $026D930A,
        $9C0906A9, $EB0E363F, $72076785, $05005713,
        $95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38,
        $92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21,
        $86D3D2D4, $F1D4E242, $68DDB3F8, $1FDA836E,
        $81BE16CD, $F6B9265B, $6FB077E1, $18B74777,
        $88085AE6, $FF0F6A70, $66063BCA, $11010B5C,
        $8F659EFF, $F862AE69, $616BFFD3, $166CCF45,
        $A00AE278, $D70DD2EE, $4E048354, $3903B3C2,
        $A7672661, $D06016F7, $4969474D, $3E6E77DB,
        $AED16A4A, $D9D65ADC, $40DF0B66, $37D83BF0,
        $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9,
        $BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6,
        $BAD03605, $CDD70693, $54DE5729, $23D967BF,
        $B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94,
        $B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D
    }
    
    define_function integer crc16 (char crcString16[255]) {
        stack_var integer m_crc16
        stack_var integer i
        m_crc16 = $0000
        for(i = 1; i < length_string(crcString16)+1; i++) {
    	m_crc16 = (m_crc16 >> 8) ^ g_pCRC16Tab[(crcString16[i] ^ (m_crc16 & $FF))+1];
        }
        return m_crc16
    }
    
    define_function integer crc16c (char crcString16c[255]) {
        stack_var integer m_crc16c
        stack_var integer i
        m_crc16c = $ffff
        for(i = 1; i < length_string(crcString16c)+1; i++) {
    	m_crc16c = g_pCRC16CcittTable[((m_crc16c >> 8) ^ crcString16c[i])+1] ^ (m_crc16c << 8);
        }
        return m_crc16c
    }
    
    define_function integer crc16x (char crcString16x[255]) {
        stack_var integer m_crc16x
        stack_var integer i
        m_crc16x = $0000
        for(i = 1; i < length_string(crcString16x)+1; i++) {
    	m_crc16x = g_pCRC16XModemTable[((m_crc16x ^ crcString16x[i]) & $FF)+1] ^ (m_crc16x >> 8);
        }
        return m_crc16x
    }
    
    define_function long crc32 (char crcString32[255]) {
        stack_var long m_crc32
        stack_var integer i
        m_crc32 = $FFFFFFFF
        for(i = 1; i < length_string(crcString32)+1; i++) {
    	m_crc32 = (m_crc32 >> 8) ^ g_pCRC32Tab[(crcString32[i] ^ (m_crc32 & $FF))+1]
        }
        return ~m_crc32
    }
    

    Here are cleaner chksum functions with lookup tables. It includes:

    CRC16 (function crc16)
    CRC16.CCITT (function crc16c)
    CRC16.XMODEM (function crc16x)
    CRC32 (function crc32)

    I'm thinking about doing MD2/4/5, SHA1/256/384/512, Base64, CRC64.. anyone have any need of those?
  • annuelloannuello Posts: 294
    Md5

    I'd love an MD5. :-)
  • A correct implementation of MD5 for NetLinx would be great. I found one a long time ago but it only worked for content with a maximum length of 120 characters :-(

    An implementation of Base64 can be found in i!-EquipmentMonitor, which is an "integration! Solutions" application and available for download from the AMX web site.
    Take a look at i!-EquipmentMonitorOut.axi. The Base64 function included there is used for SMTP authentication (for sending emails from NetLinx).

    Regards, Harald
  • AMXJeffAMXJeff Posts: 450
    Md5

    If you really need to use MD5 there is a module that I wrote that will perform MD5 encryption. Wont give the source code for the module away for various reasons, but I will send you the token. Just email me...

    Below is how to use the module...
    DEFINE_VARIABLE
    
    CHAR cTestSecret[] = 'ANY OLD SECRET'
    
    DEFINE_START
    
    DEFINE_MODULE 'Cypher Module' modCypher(vdvCypher);
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP,0]
    {
      PUSH:
      {
        // Request Module to Encrypt MD5
        SEND_COMMAND vdvCypher,"'CYPHER-',cTestSecret";  
        
        // Wait until the response from the module
        Wait_Until (LENGTH_STRING(cCypher)) 'Test'
        {
          // Tests if Response is valid.
          SEND_COMMAND vdvCypher,"'CYPHER TEST-',cTestSecret,',',cCypher"; 
          cCypher = ""; 
        }  
      }
    }
    
    DATA_EVENT[vdvCypher]
    {
      COMMAND:
      {
        STACK_VAR CHAR cTrash[100];
        
        SELECT  
        {
          // Encrypted Secret
          ACTIVE (FIND_STRING(DATA.TEXT,'CYPHER-',1)):
          {           
            cTrash = REMOVE_STRING(DATA.TEXT,'CYPHER-',1);
            cCypher = Data.Text
          }      
          // Test 'PASSED' or 'FAILED'
          ACTIVE (FIND_STRING(DATA.TEXT,'CYPHER TEST-',1)):
          {        
            SEND_STRING 0,DATA.TEXT
          }      
        }
      }
    }
    
  • jweatherjweather Posts: 320
    MD5 is actually surprisingly simple... my suggestion is to start from a Javascript implementation and translate it into NetLinx. Here is one example: http://pajhome.org.uk/crypt/md5/

    Jeremy
  • viningvining Posts: 4,368
    Does anyone have a MD5 ecryption module they would like to share?
  • Question

    Hello,

    does anyone has an example for CRC16-checksum with a polynom 1002 ?

    many thanks for help
  • AMXJeffAMXJeff Posts: 450
    I do not know if this is what your looking for but here is a CRC16 that uses a polynomial...
    DEFINE_FUNCTION INTEGER crc16Poly(CHAR cBytes[])
    {
    	STACK_VAR INTEGER nCRC;
    	STACK_VAR INTEGER nPoly;
    	STACK_VAR INTEGER nByte;
    	STACK_VAR INTEGER nBit;
    	STACK_VAR CHAR bBit;
    	STACK_VAR CHAR bC15;
    	
    	nCRC = $FFFF;
    	nPoly = $1021;
    	
    	FOR (nByte = 1; nByte <= LENGTH_STRING(cBytes); nByte++)
    	{
    		FOR (nBit = 0; nBit < 8; nBit++)
    		{
    			bBit = ((cBytes[nByte] >> (7-nBit) & 1) == 1);
    			bC15 = ((nCRC >> 15 & 1) == 1);
    			
    			nCRC = TYPE_CAST(nCRC << 1);
    			
    			if (bBit ^ bC15)
    				nCRC = nCRC ^ nPoly;
    		}
    	}
    	
    	nCRC = nCRC & $FFFF;
    	
    	RETURN nCRC;
    }
    
  • jwellsjwells Posts: 25
    Hi,
    I'm trying to implement the CRC16-CITT lookup as shown in the example, but getting a "Converting type [Long] to [INTEGER] when compiling. Sorry if this is a basic question, but really keen to use this checksum

    Cheers
  • Joe HebertJoe Hebert Posts: 2,159
    jwells wrote: »
    Hi,
    I'm trying to implement the CRC16-CITT lookup as shown in the example, but getting a "Converting type [Long] to [INTEGER] when compiling.
    Are you referring to the code that AMXJeff posted on 01/31? It compiles fine for me if you copy the code exactly as is. You should only get the Long to Integer warning if you leave out the TYPE_CAST.

    nCRC = TYPE_CAST(nCRC << 1); //no warning

    nCRC = nCRC << 1; //Long to Integer warning.
  • jwellsjwells Posts: 25
    I was having an issue with the code posted by kphlight 07-31-2006. Specifically the CRC16-CITT table.

    its this line that seems to be causing the issue with Converting type [Long] to [INTEGER]
    m_crc16c = g_pCRC16CcittTable[((m_crc16c >> 8) ^ crcString16c)+1] ^ (m_crc16c << 8);
  • AMXJeffAMXJeff Posts: 450
    jwells wrote: »
    I was having an issue with the code posted by kphlight 07-31-2006. Specifically the CRC16-CITT table.

    its this line that seems to be causing the issue with Converting type [Long] to [INTEGER]
    m_crc16c = g_pCRC16CcittTable[((m_crc16c >> 8) ^ crcString16c)+1] ^ (m_crc16c << 8);

    This is actually documented as a CRC16-CITT checksum as well...
    DEFINE_FUNCTION INTEGER crc16Poly(CHAR cBytes[])
    {
    	STACK_VAR INTEGER nCRC;
    	STACK_VAR INTEGER nPoly;
    	STACK_VAR INTEGER nByte;
    	STACK_VAR INTEGER nBit;
    	STACK_VAR CHAR bBit;
    	STACK_VAR CHAR bC15;
    	
    	nCRC = $FFFF;
    	nPoly = $1021;
    	
    	FOR (nByte = 1; nByte <= LENGTH_STRING(cBytes); nByte++)
    	{
    		FOR (nBit = 0; nBit < 8; nBit++)
    		{
    			bBit = ((cBytes[nByte] >> (7-nBit) & 1) == 1);
    			bC15 = ((nCRC >> 15 & 1) == 1);
    			
    			nCRC = TYPE_CAST(nCRC << 1);
    			
    			if (bBit ^ bC15)
    				nCRC = nCRC ^ nPoly;
    		}
    	}
    	
    	nCRC = nCRC & $FFFF;
    	
    	RETURN nCRC;
    }
    
  • jwellsjwells Posts: 25
    Cheers,
    This seems to be compiling and producing a result I was looking for, although it seem to be inverted as I'm looking for $2C09 and getting $92C


    AMXJeff wrote: »
    This is actually documented as a CRC16-CITT checksum as well...
    DEFINE_FUNCTION INTEGER crc16Poly(CHAR cBytes[])
    {
    	STACK_VAR INTEGER nCRC;
    	STACK_VAR INTEGER nPoly;
    	STACK_VAR INTEGER nByte;
    	STACK_VAR INTEGER nBit;
    	STACK_VAR CHAR bBit;
    	STACK_VAR CHAR bC15;
    	
    	nCRC = $FFFF;
    	nPoly = $1021;
    	
    	FOR (nByte = 1; nByte <= LENGTH_STRING(cBytes); nByte++)
    	{
    		FOR (nBit = 0; nBit < 8; nBit++)
    		{
    			bBit = ((cBytes[nByte] >> (7-nBit) & 1) == 1);
    			bC15 = ((nCRC >> 15 & 1) == 1);
    			
    			nCRC = TYPE_CAST(nCRC << 1);
    			
    			if (bBit ^ bC15)
    				nCRC = nCRC ^ nPoly;
    		}
    	}
    	
    	nCRC = nCRC & $FFFF;
    	
    	RETURN nCRC;
    }
    
  • AMXJeffAMXJeff Posts: 450
    jwells wrote: »
    Cheers,
    This seems to be compiling and producing a result I was looking for, although it seem to be inverted as I'm looking for $2C09 and getting $92C

    little endian vs big endian I would expect...
    INTEGER CRC16Value;
    CHAR lowbyte;
    CHAR highbyte;
    
    CRC16Value = crc16Poly(data);
    
    lowbyte = CRC16Value &#37; $100; // gets you the $2C
    highbyte = CRC16Value / $100; // gets you the $09
    
    SEND_STRING dvDevice,"data, lowbyte, highbyte";
    
    
  • Niccol?Niccol? Posts: 10
    CRC16 x25

    Hello amx world,

    Does anyone has a working example / function how to build CRC16-x25?
    This is an example that I should calculate.
    $00,$00,$03,$00,$12,$6c,$a5,$00,$00,$31,$31,$31,$31,$31,$31,$31,$31,$00 CRC low - CRC high ($D6,$2C)
    Thanx.
  • TurnipTruckTurnipTruck Posts: 1,485
    AMXJeff wrote: »
    I do not know if this is what your looking for but here is a CRC16 that uses a polynomial...
    DEFINE_FUNCTION INTEGER crc16Poly(CHAR cBytes[])
    {
    STACK_VAR INTEGER nCRC;
    STACK_VAR INTEGER nPoly;
    STACK_VAR INTEGER nByte;
    STACK_VAR INTEGER nBit;
    STACK_VAR CHAR bBit;
    STACK_VAR CHAR bC15;
    
    nCRC = $FFFF;
    nPoly = $1021;
    
    FOR (nByte = 1; nByte <= LENGTH_STRING(cBytes); nByte++)
    {
    FOR (nBit = 0; nBit < 8; nBit++)
    {
    bBit = ((cBytes[nByte] >> (7-nBit) & 1) == 1);
    bC15 = ((nCRC >> 15 & 1) == 1);
    
    nCRC = TYPE_CAST(nCRC << 1);
    
    if (bBit ^ bC15)
    nCRC = nCRC ^ nPoly;
    }
    }
    
    nCRC = nCRC & $FFFF;
    
    RETURN nCRC;
    }
    

    I realize that this a massive thread revival. How could this function be revised to calculate an 8 bit CRC?

    Thank you!
Sign In or Register to comment.