BASIC

Author Topic: Updating A Program  (Read 6114 times)

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #15 on: 2009-Nov-17 »
This may be of more help if anyone has the time to look at this for me than the heaps of links on the last post.

This page
http://www.lammertbies.nl/comm/info/crc-calculation.html?crc=abc&method=ascii
generates the "correct" CRC32 value. It also has source, so I would assume the source matches the results the page gives you.

The source is in
[/url]http://www.lammertbies.nl/download/lib_crc.zip[/url] Relevant bits reproduced here. CRC Library :-
Code: GLBasic [Select]


    /*******************************************************************\
    *                                                                   *
    *   #define P_xxxx                                                  *
    *                                                                   *
    *   The CRC's are computed using polynomials. The  coefficients     *
    *   for the algorithms are defined by the following constants.      *
    *                                                                   *
    \*******************************************************************/


#define                 P_32        0xEDB88320L




    /*******************************************************************\
    *                                                                   *
    *   static int crc_tab...init                                       *
    *   static unsigned ... crc_tab...[]                                *
    *                                                                   *
    *   The algorithms use tables with precalculated  values.  This     *
    *   speeds  up  the calculation dramaticaly. The first time the     *
    *   CRC function is called, the table for that specific  calcu-     *
    *   lation  is set up. The ...init variables are used to deter-     *
    *   mine if the initialization has taken place. The  calculated     *
    *   values are stored in the crc_tab... arrays.                     *
    *                                                                   *
    *   The variables are declared static. This makes them  invisi-     *
    *   ble for other modules of the program.                           *
    *                                                                   *
    \*******************************************************************/



static int              crc_tab32_init          = FALSE;


static unsigned long    crc_tab32[256];



    /*******************************************************************\
    *                                                                   *
    *   static void init_crc...tab();                                   *
    *                                                                   *
    *   Three local functions are used  to  initialize  the  tables     *
    *   with values for the algorithm.                                  *
    *                                                                   *
    \*******************************************************************/


static void             init_crc32_tab( void );



    /*******************************************************************\
    *                                                                   *
    *   unsigned long update_crc_32( unsigned long crc, char c );       *
    *                                                                   *
    *   The function update_crc_32 calculates a  new  CRC-32  value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/


unsigned long update_crc_32( unsigned long crc, char c ) {

    unsigned long tmp, long_c;

    long_c = 0x000000ffL & (unsigned long) c;

    if ( ! crc_tab32_init ) init_crc32_tab();

    tmp = crc ^ long_c;
    crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];

    return crc;

}  /* update_crc_32 */





    /*******************************************************************\
    *                                                                   *
    *   static void init_crc32_tab( void );                             *
    *                                                                   *
    *   The function init_crc32_tab() is used  to  fill  the  array     *
    *   for calculation of the CRC-32 with values.                      *
    *                                                                   *
    \*******************************************************************/


static void init_crc32_tab( void ) {

    int i, j;
    unsigned long crc;

    for (i=0; i<256; i++) {

        crc = (unsigned long) i;

        for (j=0; j<8; j++) {

            if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
            else                     crc =   crc >> 1;
        }

        crc_tab32[i] = crc;
    }

    crc_tab32_init = TRUE;

}  /* init_crc32_tab */
 

Test code (Hopefully I've trimmed all the appropriate bits!!!)
Code: GLBasic [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lib_crc.h"

#define MAX_STRING_SIZE 2048



void main( int argc, char *argv[] ) {

    char input_string[MAX_STRING_SIZE];
    char *ptr, *dest, hex_val, prev_byte;
    unsigned short crc_16, crc_16_modbus, crc_ccitt_ffff, crc_ccitt_0000, crc_ccitt_1d0f, crc_dnp, crc_sick, crc_kermit;
    unsigned short low_byte, high_byte;
    unsigned long crc_32;
    int a, ch, do_ascii, do_hex;
    FILE *fp;

    do_ascii = TRUE;


    if ( do_ascii  ) {

        printf( "Input: " );
        fgets( input_string, MAX_STRING_SIZE-1, stdin );
    }

    if ( do_ascii ) {

        ptr = input_string;
        while ( *ptr  &&  *ptr != &#39;\r&#39;  &&  *ptr != &#39;\n&#39; ) ptr++;
        *ptr = 0;
    }




    a = 1;

    do {

        crc_32         = 0xffffffffL;



        if ( do_ascii ) {

            prev_byte = 0;
            ptr       = input_string;

            while ( *ptr ) {

                crc_32         = update_crc_32(     crc_32,         *ptr            );

                prev_byte = *ptr;
                ptr++;
            }
        }



            else printf( "%s : cannot open file\n", argv[a] );
        }



        crc_32    ^= 0xffffffffL;

        printf( "%s%s%s :\nCRC32              = 0x%08lX  /  %lu\n"
                    , crc_32,         crc_32     );

        a++;

    } while ( a < argc );

}  /* main (tst_crc.c) */
 

Here's the section of my code that should do the same thing
Code: GLBasic [Select]
// ------------------------------------------------------------- //
// ---  CALC_CRC32_METHOD5  ---
// ------------------------------------------------------------- //
FUNCTION Calc_CRC32_Method5: CurrentChar%
                        // Algorithm
                        //                  crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];

                        LOCAL AA%,BB%,CC%,DD%,EE%
                       
                        AA%=ASR(CRCValue%,8)
                        BB%=BAND(CurrentChar%,0xFF)
                        CC%=CRC32_Table[BB%]
                        CRCValue=BXOR(AA,CC)

ENDFUNCTION // CALC_CRC32_METHOD5

And trying Method 5 in my code against a test file, I still get a different CRC to all the testing programs *sigh*
« Last Edit: 2009-Nov-17 by FutureCow »

MrTAToad

  • Guest
Re: Updating A Program
« Reply #16 on: 2009-Nov-17 »
As long as it produces a correct result for a file, I dont think it would matter whether it matches an online system.

I want to move over to SHA-2, so it might all become moot anyway :)

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #17 on: 2009-Nov-17 »
But that's exactly the reason I've spent so much time trying to get it working. How do you know it
Quote
produces a correct result for a file
if you can't get it to match working implementations? If I can get the expected results, then I know I'm producing a checksum with a very good unique result rate. If I am using effectively my own algorithm (which is what I'm doing if I'm not matching results from working implementations) then for all I know my code might be capable of producing only e.g. 10 unique values rather than thousands/millions, and that's not the point of using a checksum routine.

MrTAToad

  • Guest
Re: Updating A Program
« Reply #18 on: 2009-Nov-17 »
I'll have to see what the source code to the CRC32 code is like - see if I can get it working for you

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #19 on: 2009-Nov-17 »
Thanks, I've tried everything I can think of.

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10695
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Updating A Program
« Reply #20 on: 2009-Nov-17 »
It has to do with signed/unsigned from what I quickly checked.
Very bad.
Can you use inline, if you really want the exact same values?

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #21 on: 2009-Nov-17 »
Thanks Gernot, at least I know why it doesn't work now!!! THANKS!  :nw:
I tried to use inline, but I have very little idea of what I"m doing!!! I get all sorts of compiler errors!   *laugh*

I went looking for a "beginners" guide on how to do inline (eg. getting values back from your C code etc) and couldn't find anything. I can do basic C but haven't worked out how to interface C and GLBasic yet. I'll figure it out at some later when I don't have lots of work on my board game to do.

If I declared a variable inline as a unsigned long then used it in GLBasic would that work or would the first GLBasic command I did on it typecast it? (I'm 99% sure it would typecast, but I'll ask anyway!)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10695
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Updating A Program
« Reply #22 on: 2009-Nov-17 »
Code: GLBasic [Select]


LOCAL text$
text$ = "The quick borwn fox jumps over the lazy dog"

STDOUT "CRC of:"+text$+"\nCRC:"+Calc_crc32(text$)+"\n"
KEYWAIT




FUNCTION Calc_crc32%: ascii$
INLINE
        extern unsigned long update_crc_32(unsigned long, char);
        unsigned long crc = 0xffffffff;

        int lng = LEN(ascii_Str);
        const char* pC = ascii_Str.c_str();
        for(int i=0; i<lng; ++i)
        {
                crc = update_crc_32(crc, *pC++);
        }
        return crc;
ENDINLINE
ENDFUNCTION



INLINE

    /*******************************************************************\
    *                                                                   *
    *   #define P_xxxx                                                  *
    *                                                                   *
    *   The CRC&#39;s are computed using polynomials. The  coefficients     *
    *   for the algorithms are defined by the following constants.      *
    *                                                                   *
    \*******************************************************************/


#define                 P_32        0xEDB88320L




    /*******************************************************************\
    *                                                                   *
    *   static int crc_tab...init                                       *
    *   static unsigned ... crc_tab...[]                                *
    *                                                                   *
    *   The algorithms use tables with precalculated  values.  This     *
    *   speeds  up  the calculation dramaticaly. The first time the     *
    *   CRC function is called, the table for that specific  calcu-     *
    *   lation  is set up. The ...init variables are used to deter-     *
    *   mine if the initialization has taken place. The  calculated     *
    *   values are stored in the crc_tab... arrays.                     *
    *                                                                   *
    *   The variables are declared static. This makes them  invisi-     *
    *   ble for other modules of the program.                           *
    *                                                                   *
    \*******************************************************************/



static int              crc_tab32_init          = FALSE;


static unsigned long    crc_tab32[256];



    /*******************************************************************\
    *                                                                   *
    *   static void init_crc...tab();                                   *
    *                                                                   *
    *   Three local functions are used  to  initialize  the  tables     *
    *   with values for the algorithm.                                  *
    *                                                                   *
    \*******************************************************************/


static void             init_crc32_tab( void );



    /*******************************************************************\
    *                                                                   *
    *   unsigned long update_crc_32( unsigned long crc, char c );       *
    *                                                                   *
    *   The function update_crc_32 calculates a  new  CRC-32  value     *
    *   based  on  the  previous value of the CRC and the next byte     *
    *   of the data to be checked.                                      *
    *                                                                   *
    \*******************************************************************/


unsigned long update_crc_32( unsigned long crc, char c ) {

    unsigned long tmp, long_c;

    long_c = 0x000000ffL & (unsigned long) c;

    if ( ! crc_tab32_init ) init_crc32_tab();

    tmp = crc ^ long_c;
    crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];

    return crc;

}  /* update_crc_32 */





    /*******************************************************************\
    *                                                                   *
    *   static void init_crc32_tab( void );                             *
    *                                                                   *
    *   The function init_crc32_tab() is used  to  fill  the  array     *
    *   for calculation of the CRC-32 with values.                      *
    *                                                                   *
    \*******************************************************************/


static void init_crc32_tab( void ) {

    int i, j;
    unsigned long crc;

    for (i=0; i<256; i++) {

        crc = (unsigned long) i;

        for (j=0; j<8; j++) {

            if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
            else                     crc =   crc >> 1;
        }

        crc_tab32[i] = crc;
    }

    crc_tab32_init = TRUE;

}  /* init_crc32_tab */
ENDINLINE
 

This works and returns the same crc as the C program you posted. (obviously)
You can load a file into a string (GLBasic can handle '\0' (null) characters in a string w/o problems) and then calculate the CRC or if.

Offline FutureCow

  • HelpEditor
  • Prof. Inline
  • ******
  • Posts: 680
    • View Profile
Re: Updating A Program
« Reply #23 on: 2009-Nov-17 »
AWESOME! I'll test it tomorrow (busy on my board game right now!!!)
As always Gernot, you're the greatest!!!!  Come to Australia and I'll buy you a beer or 10! :booze: