CRC32

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Don

    CRC32

    Hi NG.

    Does anyone know of a place where I could download/get a C implementation of
    a CRC32 check.
    I would like a simple function that, for example, had a pointer to where the
    data to be CRC32 calculated reside, an indication of the length of the data
    and perhaps the polynomium as input arguments and then would return the
    calculated crc32 value like e.g. an unsigned long.

    Don


  • Pieter Droogendijk

    #2
    Re: CRC32

    On Wed, 30 Jul 2003 14:29:42 +0200
    "Don" <nono@spam.dk > wrote:[color=blue]
    > Hi NG.
    >
    > Does anyone know of a place where I could download/get a C implementation of
    > a CRC32 check.
    > I would like a simple function that, for example, had a pointer to where the
    > data to be CRC32 calculated reside, an indication of the length of the data
    > and perhaps the polynomium as input arguments and then would return the
    > calculated crc32 value like e.g. an unsigned long.
    >
    > Don
    >
    >[/color]

    Learn the value of search engines!
    A simple google search provided me with:


    --
    main(int c,char*k,char*s ){c>0?main(0,"a dceoX$_k6][^hn","-7\
    0#05&'40$.6'+). 3+1%30"),puts(" "):*s?c=!c?-*s:(putchar(45) ,c
    ),putchar(main( c,k+=*s-c*-1,s+1)):(s=0);r eturn!s?10:10+* k;}

    Comment

    • Mark A. Odell

      #3
      Re: CRC32

      Pieter Droogendijk <gin@binky.home unix.org> wrote in
      news:2003073014 4653.6c4cd71d.g in@binky.homeun ix.org:
      [color=blue][color=green]
      >> Does anyone know of a place where I could download/get a C
      >> implementation of a CRC32 check.
      >> I would like a simple function that, for example, had a pointer to
      >> where the data to be CRC32 calculated reside, an indication of the
      >> length of the data and perhaps the polynomium as input arguments and
      >> then would return the calculated crc32 value like e.g. an unsigned
      >> long.
      >>
      >> Don
      >>
      >>[/color]
      >
      > Learn the value of search engines!
      > A simple google search provided me with:
      > http://remus.rutgers.edu/~rhoads/Code/crc-32b.c[/color]

      I grabbed this and was confused by this function's use of 'int char'.:

      unsigned long get_crc( FILE *fp) /* calculate the crc value */
      {
      register unsigned long crc;
      int char; <------------------ NOTE

      crc = 0xFFFFFFFF;
      while ((char = getc(fp)) != EOF)
      crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];

      return( crc^0xFFFFFFFF );
      }

      What's with the NOTE'd line. Could someone really have published a
      function with this sort of error?

      --
      - Mark ->
      --

      Comment

      • Arthur J. O'Dwyer

        #4
        Re: CRC32


        On Wed, 30 Jul 2003, Mark A. Odell wrote:[color=blue]
        >
        > Pieter Droogendijk <gin@binky.home unix.org> wrote...[color=green]
        > >
        > > http://remus.rutgers.edu/~rhoads/Code/crc-32b.c[/color]
        >
        > I grabbed this and was confused by this function's use of 'int char'.
        >
        > unsigned long get_crc( FILE *fp) /* calculate the crc value */
        > {
        > register unsigned long crc;
        > int char; <------------------ NOTE
        >
        > crc = 0xFFFFFFFF;
        > while ((char = getc(fp)) != EOF)
        > crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];
        >
        > return( crc^0xFFFFFFFF );
        > }
        >
        > What's with the NOTE'd line. Could someone really have published a
        > function with this sort of error?[/color]

        Yes. :) That is absolutely ridiculous. Maybe the OP should look
        somewhere else for more reliable code, since this was obviously
        never tested in a real program.

        The lines

        #ifndef FILE /* if FILE type not defined */
        #include <stdio.h> /* then bring it in */
        #endif

        should also have raised several red flags. I'm going to mail
        the guy right away and point it out.

        http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky

        -Arthur

        Comment

        • Don

          #5
          Re: CRC32

          "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message
          news:Pine.LNX.4 .55L-032.03073009492 71.2636@unix44. andrew.cmu.edu. ..[color=blue]
          >
          > On Wed, 30 Jul 2003, Mark A. Odell wrote:[color=green]
          > >
          > > Pieter Droogendijk <gin@binky.home unix.org> wrote...[color=darkred]
          > > >
          > > > http://remus.rutgers.edu/~rhoads/Code/crc-32b.c[/color]
          > >
          > > I grabbed this and was confused by this function's use of 'int char'.
          > >
          > > unsigned long get_crc( FILE *fp) /* calculate the crc value */
          > > {
          > > register unsigned long crc;
          > > int char; <------------------ NOTE
          > >
          > > crc = 0xFFFFFFFF;
          > > while ((char = getc(fp)) != EOF)
          > > crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];
          > >
          > > return( crc^0xFFFFFFFF );
          > > }
          > >
          > > What's with the NOTE'd line. Could someone really have published a
          > > function with this sort of error?[/color]
          >
          > Yes. :) That is absolutely ridiculous. Maybe the OP should look
          > somewhere else for more reliable code, since this was obviously
          > never tested in a real program.
          >
          > The lines
          >
          > #ifndef FILE /* if FILE type not defined */
          > #include <stdio.h> /* then bring it in */
          > #endif
          >
          > should also have raised several red flags. I'm going to mail
          > the guy right away and point it out.
          >
          > http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
          >
          > -Arthur[/color]



          Hi Arthur. Thank you for the reply (and the rest of you too). I am a little
          puzzled by the code presented by the link you gave me.

          uLong crc32(uLong crc, char const *buf, size_t len) {
          if (crc_table[255] == 0)
          make_crc_table( );
          crc ^= 0xffffffff;
          while (len--)
          crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
          return crc ^ 0xffffffff;
          }

          Why does the function take a uLong crc as argument, change it and return the
          same......would this cause the function to update the very ulong as I am
          calling the function with? For example if I called the function like:

          void myfunc() {
          unsigned long test;
          crc32(test,.... ....);
          }

          then my ulong test would hold the crc32 value?

          Also why are the buf pointer constant.....? The pointer points to chars,
          could I just easily change this to uint's instead (uLong crc32(uLong crc,
          unsigned int const *buf, size_t len)) if I had an array of uint that I
          needed to calculate the crc32 from.

          Final question :-), what is the "size_t" type?????


          Don


          Comment

          • Eric Sosman

            #6
            Re: CRC32

            Don wrote:[color=blue]
            >
            > Hi Arthur. Thank you for the reply (and the rest of you too). I am a little
            > puzzled by the code presented by the link you gave me.[/color]

            Don, from your questions it appears you may be in over
            your head. Splash onward if you feel so inclined, but it
            might be wise to take a few swimming lessons first -- in
            other words, you need to brush up both on your C and on
            your understanding of programming in general. Nonetheless:
            [color=blue]
            > uLong crc32(uLong crc, char const *buf, size_t len) {
            > if (crc_table[255] == 0)
            > make_crc_table( );
            > crc ^= 0xffffffff;
            > while (len--)
            > crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
            > return crc ^ 0xffffffff;
            > }
            >
            > Why does the function take a uLong crc as argument, change it and return the
            > same......would this cause the function to update the very ulong as I am
            > calling the function with? For example if I called the function like:[/color]

            Presumably so you can calculate the CRC of a lot of data
            in a "piecewise" fashion. For example, many machines will have
            difficulty finding enough memory to hold a one-terabyte file
            all at once so as to calculate the CRC in one operation. Instead,
            you'd read a convenient-sized chunk, start the CRC calculation
            with one call to crc32(), then read another chunk and call crc32()
            again to continue the calculation, and so on.
            [color=blue]
            > void myfunc() {
            > unsigned long test;
            > crc32(test,.... ....);
            > }
            >
            > then my ulong test would hold the crc32 value?[/color]

            No, for two reasons. First, you've never initialized `test'
            to anything, so it has some indeterminate "garbage" value and
            there's no telling what might happen when the crc32() function
            tries to make use of that value. Second, when the crc32()
            function returns the updated CRC, you never store it anywhere
            so the result of the work is simply forgotten.

            You *really* need to refresh your understanding of C, of
            functions, of variables and values, of ... well, of a lot.
            [color=blue]
            > Also why are the buf pointer constant.....?[/color]

            The crc32() function is advertising the fact that it does
            not intend to change the contents of the buffer. If the person
            writing the crc32() function made an inadvertent finger-slip
            that attempted to write through the `buf' pointer, the compiler
            would complain.
            [color=blue]
            > The pointer points to chars,
            > could I just easily change this to uint's instead (uLong crc32(uLong crc,
            > unsigned int const *buf, size_t len)) if I had an array of uint that I
            > needed to calculate the crc32 from.[/color]

            No, because the algorithm as written consumes data one
            byte at a time, no less and no more. You could adapt the method
            to wider types, but the crc_table[] array would need to grow.
            For example, assuming 8-bit `char' and 32-bit `unsigned int',
            the crc_table[] array would need to occupy sixteen gigabytes.
            Many machines are not even capable of thinking about that much
            memory, never mind actually using it.
            [color=blue]
            > Final question :-), what is the "size_t" type?????[/color]

            You really, *really*, REALLY need to brush up on your C.
            Consult any C textbook or reference book written in the last
            fifteen years or so; even the bad ones will explain `size_t'.

            --
            Eric.Sosman@sun .com

            Comment

            • Glenn C. Rhoads

              #7
              Re: CRC32

              "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message news:<Pine.LNX. 4.55L-032.03073009492 71.2636@unix44. andrew.cmu.edu> ...[color=blue]
              > On Wed, 30 Jul 2003, Mark A. Odell wrote:[color=green]
              >>
              >> Pieter Droogendijk <gin@binky.home unix.org> wrote...[color=darkred]
              >>>
              >>> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c[/color]
              >>
              >> I grabbed this and was confused by this function's use of 'int char'.
              >>
              >> unsigned long get_crc( FILE *fp) /* calculate the crc value */
              >> {
              >> register unsigned long crc;
              >> int char; <------------------ NOTE
              >>
              >> crc = 0xFFFFFFFF;
              >> while ((char = getc(fp)) != EOF)
              >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];
              >>
              >> return( crc^0xFFFFFFFF );
              >> }
              >>
              >> What's with the NOTE'd line. Could someone really have published a
              >> function with this sort of error?[/color]
              >
              > Yes. :) That is absolutely ridiculous. Maybe the OP should look
              > somewhere else for more reliable code, since this was obviously
              > never tested in a real program.
              >
              > The lines
              >
              > #ifndef FILE /* if FILE type not defined */
              > #include <stdio.h> /* then bring it in */
              > #endif
              >
              > should also have raised several red flags. I'm going to mail
              > the guy right away and point it out.
              >
              > http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
              >
              > -Arthur[/color]

              From my email response:


              The line "int char" is *not* a syntax error! In fact there is a very
              good reason for using a variable of type "int" instead of "char." The
              function "getc" can return any value from the character set *plus*
              the special non-character value EOF. According to the C standard, the
              type "char" is guaranteed to contain enough bits to hold all of the
              values corresponding to the machine's character set; it is *not*
              guaranteed to be able to hold the additional EOF value (without
              possibly mixing up EOF with some actual character value). Thus, to
              ensure that the code works across all implementations , you need to
              declare the variable as an "int" instead of a "char." For
              portability reasons, it is good practice to always declare character
              data as type "int" except when you are declaring an array of
              characters.

              [color=blue]
              > (Also, the lines
              >
              > #ifndef FILE
              > #include <stdio.h>
              > #endif
              >
              > are suspicious; the #ifndef and #endif directives
              > are completely useless and irrelevant there.)[/color]

              I disagree with this claim too. There are two distinct methods of
              making use of this crc code as part of a system library. First, you
              may want to compile the crc code separately to generate an object
              file only and then make the object file available as part of your
              library while hiding the actual source code. Alternatively, you may
              want to make the actual source code available and have the user
              compile their source code and the crc source code together at once.
              To use the first method, you need to include "stdio.h" so the
              compiler will not complain about the type "FILE." But if include
              "stdio.h" without the preprocessor directives #ifndef and #endif,
              then you will run into a problem using the second method if your own
              source code file also includes "stdio.h." Since I cannot know in
              advance which method someone might use, I used the above method
              to let you to use either method without running into a problem.
              Having the #ifndef and #endif directives will not hurt you if your
              preferred method does not need them.

              Comment

              • Carsten Hansen

                #8
                Re: CRC32


                "Glenn C. Rhoads" <gcrhoads@yahoo .com> wrote in message
                news:3396efc6.0 307301641.261c3 197@posting.goo gle.com...[color=blue]
                > "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message[/color]
                news:<Pine.LNX. 4.55L-032.03073009492 71.2636@unix44. andrew.cmu.edu> ...[color=blue][color=green]
                > > On Wed, 30 Jul 2003, Mark A. Odell wrote:[color=darkred]
                > >>
                > >> Pieter Droogendijk <gin@binky.home unix.org> wrote...
                > >>>
                > >>> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c
                > >>
                > >> I grabbed this and was confused by this function's use of 'int char'.
                > >>
                > >> unsigned long get_crc( FILE *fp) /* calculate the crc value */
                > >> {
                > >> register unsigned long crc;
                > >> int char; <------------------ NOTE
                > >>
                > >> crc = 0xFFFFFFFF;
                > >> while ((char = getc(fp)) != EOF)
                > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];
                > >>
                > >> return( crc^0xFFFFFFFF );
                > >> }
                > >>
                > >> What's with the NOTE'd line. Could someone really have published a
                > >> function with this sort of error?[/color]
                > >
                > > Yes. :) That is absolutely ridiculous. Maybe the OP should look
                > > somewhere else for more reliable code, since this was obviously
                > > never tested in a real program.
                > >
                > > The lines
                > >
                > > #ifndef FILE /* if FILE type not defined */
                > > #include <stdio.h> /* then bring it in */
                > > #endif
                > >
                > > should also have raised several red flags. I'm going to mail
                > > the guy right away and point it out.
                > >
                > > http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
                > >
                > > -Arthur[/color]
                >
                > From my email response:
                >
                >
                > The line "int char" is *not* a syntax error! In fact there is a very
                > good reason for using a variable of type "int" instead of "char." The
                > function "getc" can return any value from the character set *plus*
                > the special non-character value EOF. According to the C standard, the
                > type "char" is guaranteed to contain enough bits to hold all of the
                > values corresponding to the machine's character set; it is *not*
                > guaranteed to be able to hold the additional EOF value (without
                > possibly mixing up EOF with some actual character value). Thus, to
                > ensure that the code works across all implementations , you need to
                > declare the variable as an "int" instead of a "char." For
                > portability reasons, it is good practice to always declare character
                > data as type "int" except when you are declaring an array of
                > characters.
                >
                >[color=green]
                > > (Also, the lines
                > >
                > > #ifndef FILE
                > > #include <stdio.h>
                > > #endif
                > >
                > > are suspicious; the #ifndef and #endif directives
                > > are completely useless and irrelevant there.)[/color]
                >
                > I disagree with this claim too. There are two distinct methods of
                > making use of this crc code as part of a system library. First, you
                > may want to compile the crc code separately to generate an object
                > file only and then make the object file available as part of your
                > library while hiding the actual source code. Alternatively, you may
                > want to make the actual source code available and have the user
                > compile their source code and the crc source code together at once.
                > To use the first method, you need to include "stdio.h" so the
                > compiler will not complain about the type "FILE." But if include
                > "stdio.h" without the preprocessor directives #ifndef and #endif,
                > then you will run into a problem using the second method if your own
                > source code file also includes "stdio.h." Since I cannot know in
                > advance which method someone might use, I used the above method
                > to let you to use either method without running into a problem.
                > Having the #ifndef and #endif directives will not hurt you if your
                > preferred method does not need them.[/color]


                The problem with[color=blue][color=green][color=darkred]
                > >> int char; <------------------ NOTE[/color][/color][/color]
                is that char is a keyword. You cannot use it as an identifier for a
                variable.

                The problem with[color=blue][color=green]
                > > #ifndef FILE
                > > #include <stdio.h>
                > > #endif[/color][/color]
                is that FILE is not a macro. Hence it is not defined during the preprocessor
                stage of compilation, no matter whether <stdio.h> has previously been
                included or not.
                Moreover, the C standard explicitly allows a standard header to be included
                multiple times "with no effect different from being included only once". So,
                basically you have a wrong solution to a non-existing problem.

                Finally, the masking in[color=blue][color=green][color=darkred]
                > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];[/color][/color][/color]
                is superfluous. Right shifting of an unsigned is guaranteed to fill the
                vacated bits with zeros.


                Carsten Hansen


                Comment

                • Don

                  #9
                  Re: CRC32

                  "Carsten Hansen" <hansen.c@world net.att.net> wrote in message
                  news:eA2Wa.8150 7$0v4.5425606@b gtnsc04-news.ops.worldn et.att.net...[color=blue]
                  >
                  > "Glenn C. Rhoads" <gcrhoads@yahoo .com> wrote in message
                  > news:3396efc6.0 307301641.261c3 197@posting.goo gle.com...[color=green]
                  > > "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message[/color]
                  > news:<Pine.LNX. 4.55L-032.03073009492 71.2636@unix44. andrew.cmu.edu> ...[color=green][color=darkred]
                  > > > On Wed, 30 Jul 2003, Mark A. Odell wrote:
                  > > >>
                  > > >> Pieter Droogendijk <gin@binky.home unix.org> wrote...
                  > > >>>
                  > > >>> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c
                  > > >>
                  > > >> I grabbed this and was confused by this function's use of 'int char'.
                  > > >>
                  > > >> unsigned long get_crc( FILE *fp) /* calculate the crc value */
                  > > >> {
                  > > >> register unsigned long crc;
                  > > >> int char; <------------------ NOTE
                  > > >>
                  > > >> crc = 0xFFFFFFFF;
                  > > >> while ((char = getc(fp)) != EOF)
                  > > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) &[/color][/color][/color]
                  0xFF ];[color=blue][color=green][color=darkred]
                  > > >>
                  > > >> return( crc^0xFFFFFFFF );
                  > > >> }
                  > > >>
                  > > >> What's with the NOTE'd line. Could someone really have published a
                  > > >> function with this sort of error?
                  > > >
                  > > > Yes. :) That is absolutely ridiculous. Maybe the OP should look
                  > > > somewhere else for more reliable code, since this was obviously
                  > > > never tested in a real program.
                  > > >
                  > > > The lines
                  > > >
                  > > > #ifndef FILE /* if FILE type not defined */
                  > > > #include <stdio.h> /* then bring it in */
                  > > > #endif
                  > > >
                  > > > should also have raised several red flags. I'm going to mail
                  > > > the guy right away and point it out.
                  > > >
                  > > > http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
                  > > >
                  > > > -Arthur[/color]
                  > >
                  > > From my email response:
                  > >
                  > >
                  > > The line "int char" is *not* a syntax error! In fact there is a very
                  > > good reason for using a variable of type "int" instead of "char." The
                  > > function "getc" can return any value from the character set *plus*
                  > > the special non-character value EOF. According to the C standard, the
                  > > type "char" is guaranteed to contain enough bits to hold all of the
                  > > values corresponding to the machine's character set; it is *not*
                  > > guaranteed to be able to hold the additional EOF value (without
                  > > possibly mixing up EOF with some actual character value). Thus, to
                  > > ensure that the code works across all implementations , you need to
                  > > declare the variable as an "int" instead of a "char." For
                  > > portability reasons, it is good practice to always declare character
                  > > data as type "int" except when you are declaring an array of
                  > > characters.
                  > >
                  > >[color=darkred]
                  > > > (Also, the lines
                  > > >
                  > > > #ifndef FILE
                  > > > #include <stdio.h>
                  > > > #endif
                  > > >
                  > > > are suspicious; the #ifndef and #endif directives
                  > > > are completely useless and irrelevant there.)[/color]
                  > >
                  > > I disagree with this claim too. There are two distinct methods of
                  > > making use of this crc code as part of a system library. First, you
                  > > may want to compile the crc code separately to generate an object
                  > > file only and then make the object file available as part of your
                  > > library while hiding the actual source code. Alternatively, you may
                  > > want to make the actual source code available and have the user
                  > > compile their source code and the crc source code together at once.
                  > > To use the first method, you need to include "stdio.h" so the
                  > > compiler will not complain about the type "FILE." But if include
                  > > "stdio.h" without the preprocessor directives #ifndef and #endif,
                  > > then you will run into a problem using the second method if your own
                  > > source code file also includes "stdio.h." Since I cannot know in
                  > > advance which method someone might use, I used the above method
                  > > to let you to use either method without running into a problem.
                  > > Having the #ifndef and #endif directives will not hurt you if your
                  > > preferred method does not need them.[/color]
                  >
                  >
                  > The problem with[color=green][color=darkred]
                  > > >> int char; <------------------ NOTE[/color][/color]
                  > is that char is a keyword. You cannot use it as an identifier for a
                  > variable.
                  >
                  > The problem with[color=green][color=darkred]
                  > > > #ifndef FILE
                  > > > #include <stdio.h>
                  > > > #endif[/color][/color]
                  > is that FILE is not a macro. Hence it is not defined during the[/color]
                  preprocessor[color=blue]
                  > stage of compilation, no matter whether <stdio.h> has previously been
                  > included or not.
                  > Moreover, the C standard explicitly allows a standard header to be[/color]
                  included[color=blue]
                  > multiple times "with no effect different from being included only once".[/color]
                  So,[color=blue]
                  > basically you have a wrong solution to a non-existing problem.
                  >
                  > Finally, the masking in[color=green][color=darkred]
                  > > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) &[/color][/color][/color]
                  0xFF ];[color=blue]
                  > is superfluous. Right shifting of an unsigned is guaranteed to fill the
                  > vacated bits with zeros.
                  >
                  >
                  > Carsten Hansen
                  >
                  >[/color]


                  Ok. Thank you all for your help. I need to implement this crc32 check in a
                  microcontroller and I have a program now that states:

                  #define POLYNOMIAL (unsigned long)0x04c11db7

                  static unsigned long crc_table[256];

                  static void make_crc_table( ) {
                  unsigned int i, j;
                  unsigned long h = 1;
                  crc_table[0] = 0;
                  for (i = 128; i; i >>= 1) {
                  h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0);
                  /* h is now crc_table[i] */
                  for (j = 0; j < 256; j += 2*i)
                  crc_table[i+j] = crc_table[j] ^ h;
                  }
                  }


                  unsigned long crc32(unsigned long crc, char const *buf, unsigned int len) {
                  if (crc_table[255] == 0)
                  make_crc_table( );
                  crc ^= 0xffffffff;
                  while (len--)
                  crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
                  return crc ^ 0xffffffff;
                  }


                  main(){
                  unsigned char temp[10];
                  unsigned long mycrc;

                  temp[0] = 0x55;
                  temp[1] = 0x77;
                  temp[2] = 0x78;
                  temp[3] = 0x45;
                  temp[4] = 0x89;
                  temp[5] = 0x03;
                  temp[6] = 0x89;
                  temp[7] = 0x87;
                  temp[8] = 0x65;
                  temp[9] = 0x91;

                  mycrc = crc32(mycrc,tem p,10);

                  }



                  This gives me mycrc = 0xfe7c9148

                  I would like to cross-check this with some program or similar. Does anyone
                  know of a program similar to:

                  Making me capable of calculating the crc32 (instead of only crc8) of a
                  hexadecimal string?

                  Don


                  Comment

                  • Mark A. Odell

                    #10
                    Re: CRC32

                    "Don" <nono@spam.dk > wrote in news:bgao03$mgf $1@news.net.uni-c.dk:
                    [color=blue]
                    > Ok. Thank you all for your help. I need to implement this crc32 check in
                    > a microcontroller and I have a program now that states:
                    >
                    > #define POLYNOMIAL (unsigned long)0x04c11db7[/color]

                    What possible (practical) benefit is there to making this a #define
                    instead of a const var (e.g. const unsigned long polynomial = 0x04c11db7)?
                    Try finding the #define in your debugger by name.

                    --
                    - Mark ->
                    --

                    Comment

                    • Dan Pop

                      #11
                      Re: CRC32

                      In <Xns93C95ABA79F F8lkj562ghjgk1k 245lbvj@130.133 .1.4> "Mark A. Odell" <nospam@embedde dfw.com> writes:
                      [color=blue]
                      >"Don" <nono@spam.dk > wrote in news:bgao03$mgf $1@news.net.uni-c.dk:
                      >[color=green]
                      >> Ok. Thank you all for your help. I need to implement this crc32 check in
                      >> a microcontroller and I have a program now that states:
                      >>
                      >> #define POLYNOMIAL (unsigned long)0x04c11db7[/color]
                      >
                      >What possible (practical) benefit is there to making this a #define
                      >instead of a const var (e.g. const unsigned long polynomial = 0x04c11db7)?[/color]

                      You have forgotten static. And it's still better to spell it in upper
                      case, to point out that it isn't an ordinary variable.
                      [color=blue]
                      >Try finding the #define in your debugger by name.[/color]

                      Why would one want to do such a thing? You have the source code in
                      front of your eyes while using the debugger, don't you?

                      Dan
                      --
                      Dan Pop
                      DESY Zeuthen, RZ group
                      Email: Dan.Pop@ifh.de

                      Comment

                      • Randy Howard

                        #12
                        Re: CRC32

                        In article <bgao03$mgf$1@n ews.net.uni-c.dk>, nono@spam.dk says...[color=blue]
                        > I would like to cross-check this with some program or similar. Does anyone
                        > know of a program similar to:
                        > http://www.smbus.org/faq/crc8Applet.htm
                        > Making me capable of calculating the crc32 (instead of only crc8) of a
                        > hexadecimal string?
                        >
                        > Don[/color]

                        Btw, if you want a very efficient implementation, do a google search for
                        "Hacker's Delight". The website for this (very interesting) book has an
                        implementation of crc32 that is very well explained and along with that
                        is half a dozen or more implementations of it, each analyzed for
                        performance.

                        Comment

                        • Carsten Hansen

                          #13
                          Re: CRC32


                          "Don" <nono@spam.dk > wrote in message news:bgao03$mgf $1@news.net.uni-c.dk...[color=blue]
                          > "Carsten Hansen" <hansen.c@world net.att.net> wrote in message
                          > news:eA2Wa.8150 7$0v4.5425606@b gtnsc04-news.ops.worldn et.att.net...[color=green]
                          > >
                          > > "Glenn C. Rhoads" <gcrhoads@yahoo .com> wrote in message
                          > > news:3396efc6.0 307301641.261c3 197@posting.goo gle.com...[color=darkred]
                          > > > "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message[/color]
                          > > news:<Pine.LNX. 4.55L-032.03073009492 71.2636@unix44. andrew.cmu.edu> ...[color=darkred]
                          > > > > On Wed, 30 Jul 2003, Mark A. Odell wrote:
                          > > > >>
                          > > > >> Pieter Droogendijk <gin@binky.home unix.org> wrote...
                          > > > >>>
                          > > > >>> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c
                          > > > >>
                          > > > >> I grabbed this and was confused by this function's use of 'int[/color][/color][/color]
                          char'.[color=blue][color=green][color=darkred]
                          > > > >>
                          > > > >> unsigned long get_crc( FILE *fp) /* calculate the crc value */
                          > > > >> {
                          > > > >> register unsigned long crc;
                          > > > >> int char; <------------------ NOTE
                          > > > >>
                          > > > >> crc = 0xFFFFFFFF;
                          > > > >> while ((char = getc(fp)) != EOF)
                          > > > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) &[/color][/color]
                          > 0xFF ];[color=green][color=darkred]
                          > > > >>
                          > > > >> return( crc^0xFFFFFFFF );
                          > > > >> }
                          > > > >>
                          > > > >> What's with the NOTE'd line. Could someone really have published a
                          > > > >> function with this sort of error?
                          > > > >
                          > > > > Yes. :) That is absolutely ridiculous. Maybe the OP should look
                          > > > > somewhere else for more reliable code, since this was obviously
                          > > > > never tested in a real program.
                          > > > >
                          > > > > The lines
                          > > > >
                          > > > > #ifndef FILE /* if FILE type not defined */
                          > > > > #include <stdio.h> /* then bring it in */
                          > > > > #endif
                          > > > >
                          > > > > should also have raised several red flags. I'm going to mail
                          > > > > the guy right away and point it out.
                          > > > >
                          > > > > http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
                          > > > >
                          > > > > -Arthur
                          > > >
                          > > > From my email response:
                          > > >
                          > > >
                          > > > The line "int char" is *not* a syntax error! In fact there is a very
                          > > > good reason for using a variable of type "int" instead of "char." The
                          > > > function "getc" can return any value from the character set *plus*
                          > > > the special non-character value EOF. According to the C standard, the
                          > > > type "char" is guaranteed to contain enough bits to hold all of the
                          > > > values corresponding to the machine's character set; it is *not*
                          > > > guaranteed to be able to hold the additional EOF value (without
                          > > > possibly mixing up EOF with some actual character value). Thus, to
                          > > > ensure that the code works across all implementations , you need to
                          > > > declare the variable as an "int" instead of a "char." For
                          > > > portability reasons, it is good practice to always declare character
                          > > > data as type "int" except when you are declaring an array of
                          > > > characters.
                          > > >
                          > > >
                          > > > > (Also, the lines
                          > > > >
                          > > > > #ifndef FILE
                          > > > > #include <stdio.h>
                          > > > > #endif
                          > > > >
                          > > > > are suspicious; the #ifndef and #endif directives
                          > > > > are completely useless and irrelevant there.)
                          > > >
                          > > > I disagree with this claim too. There are two distinct methods of
                          > > > making use of this crc code as part of a system library. First, you
                          > > > may want to compile the crc code separately to generate an object
                          > > > file only and then make the object file available as part of your
                          > > > library while hiding the actual source code. Alternatively, you may
                          > > > want to make the actual source code available and have the user
                          > > > compile their source code and the crc source code together at once.
                          > > > To use the first method, you need to include "stdio.h" so the
                          > > > compiler will not complain about the type "FILE." But if include
                          > > > "stdio.h" without the preprocessor directives #ifndef and #endif,
                          > > > then you will run into a problem using the second method if your own
                          > > > source code file also includes "stdio.h." Since I cannot know in
                          > > > advance which method someone might use, I used the above method
                          > > > to let you to use either method without running into a problem.
                          > > > Having the #ifndef and #endif directives will not hurt you if your
                          > > > preferred method does not need them.[/color]
                          > >
                          > >
                          > > The problem with[color=darkred]
                          > > > >> int char; <------------------ NOTE[/color]
                          > > is that char is a keyword. You cannot use it as an identifier for a
                          > > variable.
                          > >
                          > > The problem with[color=darkred]
                          > > > > #ifndef FILE
                          > > > > #include <stdio.h>
                          > > > > #endif[/color]
                          > > is that FILE is not a macro. Hence it is not defined during the[/color]
                          > preprocessor[color=green]
                          > > stage of compilation, no matter whether <stdio.h> has previously been
                          > > included or not.
                          > > Moreover, the C standard explicitly allows a standard header to be[/color]
                          > included[color=green]
                          > > multiple times "with no effect different from being included only once".[/color]
                          > So,[color=green]
                          > > basically you have a wrong solution to a non-existing problem.
                          > >
                          > > Finally, the masking in[color=darkred]
                          > > > >> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) &[/color][/color]
                          > 0xFF ];[color=green]
                          > > is superfluous. Right shifting of an unsigned is guaranteed to fill the
                          > > vacated bits with zeros.
                          > >
                          > >
                          > > Carsten Hansen
                          > >
                          > >[/color]
                          >
                          >
                          > Ok. Thank you all for your help. I need to implement this crc32 check in a
                          > microcontroller and I have a program now that states:
                          >
                          > #define POLYNOMIAL (unsigned long)0x04c11db7
                          >
                          > static unsigned long crc_table[256];
                          >
                          > static void make_crc_table( ) {
                          > unsigned int i, j;
                          > unsigned long h = 1;
                          > crc_table[0] = 0;
                          > for (i = 128; i; i >>= 1) {
                          > h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0);
                          > /* h is now crc_table[i] */
                          > for (j = 0; j < 256; j += 2*i)
                          > crc_table[i+j] = crc_table[j] ^ h;
                          > }
                          > }
                          >
                          >
                          > unsigned long crc32(unsigned long crc, char const *buf, unsigned int len)[/color]
                          {[color=blue]
                          > if (crc_table[255] == 0)
                          > make_crc_table( );
                          > crc ^= 0xffffffff;
                          > while (len--)
                          > crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff];
                          > return crc ^ 0xffffffff;
                          > }
                          >
                          >
                          > main(){
                          > unsigned char temp[10];
                          > unsigned long mycrc;
                          >
                          > temp[0] = 0x55;
                          > temp[1] = 0x77;
                          > temp[2] = 0x78;
                          > temp[3] = 0x45;
                          > temp[4] = 0x89;
                          > temp[5] = 0x03;
                          > temp[6] = 0x89;
                          > temp[7] = 0x87;
                          > temp[8] = 0x65;
                          > temp[9] = 0x91;
                          >
                          > mycrc = crc32(mycrc,tem p,10);
                          >
                          > }
                          >
                          >
                          >
                          > This gives me mycrc = 0xfe7c9148
                          >
                          > I would like to cross-check this with some program or similar. Does anyone
                          > know of a program similar to:
                          > http://www.smbus.org/faq/crc8Applet.htm
                          > Making me capable of calculating the crc32 (instead of only crc8) of a
                          > hexadecimal string?
                          >
                          > Don
                          >
                          >[/color]

                          Your program has undefined behavior. You never initialize mycrc.
                          There are many variations on CRC. The one you are using here is not the most
                          common.
                          Usually one uses the reflected polynomial (0xEDB88320) to the one you are
                          using here.
                          Here are some references:
                          Michael Barr (mbarr@netrino. com)
                          Wrote Easier Said Than Done, a less-confusing guide to implementing CRC
                          algorithms. (Originally published as "Slow and Steady Never Lost the Race"
                          in the January 2000 issue of Embedded Systems Programming, pages 37-46.)
                          Ross N. Williams
                          Wrote A Painless Guide to CRC Error Detection Algorithms, a definitive
                          source of CRC information.

                          Carsten Hansen


                          Comment

                          • bd

                            #14
                            Re: CRC32

                            On Wed, 30 Jul 2003 17:41:47 -0700, Glenn C. Rhoads wrote:
                            [color=blue]
                            > "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message news:<Pine.LNX. 4.55L-032.03073009492 71.2636@unix44. andrew.cmu.edu> ...[color=green]
                            >> On Wed, 30 Jul 2003, Mark A. Odell wrote:[color=darkred]
                            >>>
                            >>> Pieter Droogendijk <gin@binky.home unix.org> wrote...
                            >>>>
                            >>>> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c
                            >>>
                            >>> I grabbed this and was confused by this function's use of 'int char'.
                            >>>
                            >>> unsigned long get_crc( FILE *fp) /* calculate the crc value */
                            >>> {
                            >>> register unsigned long crc;
                            >>> int char; <------------------ NOTE
                            >>>
                            >>> crc = 0xFFFFFFFF;
                            >>> while ((char = getc(fp)) != EOF)
                            >>> crc = ((crc>>8) & 0x00FFFFFF) ^ crc_table[ (crc^char) & 0xFF ];
                            >>>
                            >>> return( crc^0xFFFFFFFF );
                            >>> }
                            >>>
                            >>> What's with the NOTE'd line. Could someone really have published a
                            >>> function with this sort of error?[/color]
                            >>
                            >> Yes. :) That is absolutely ridiculous. Maybe the OP should look
                            >> somewhere else for more reliable code, since this was obviously
                            >> never tested in a real program.
                            >>
                            >> The lines
                            >>
                            >> #ifndef FILE /* if FILE type not defined */
                            >> #include <stdio.h> /* then bring it in */
                            >> #endif
                            >>
                            >> should also have raised several red flags. I'm going to mail
                            >> the guy right away and point it out.
                            >>
                            >> http://www.google.com/search?q=crc32+ c+source&btnI=I 'mFeelingLucky
                            >>
                            >> -Arthur[/color]
                            >
                            > From my email response:
                            >
                            >
                            > The line "int char" is *not* a syntax error! In fact there is a very
                            > good reason for using a variable of type "int" instead of "char." The
                            > function "getc" can return any value from the character set *plus*
                            > the special non-character value EOF. According to the C standard, the
                            > type "char" is guaranteed to contain enough bits to hold all of the
                            > values corresponding to the machine's character set; it is *not*
                            > guaranteed to be able to hold the additional EOF value (without
                            > possibly mixing up EOF with some actual character value). Thus, to
                            > ensure that the code works across all implementations , you need to
                            > declare the variable as an "int" instead of a "char." For
                            > portability reasons, it is good practice to always declare character
                            > data as type "int" except when you are declaring an array of
                            > characters.[/color]

                            The question is of whether 'char' is a legal variable name, I think.
                            [color=blue]
                            >[color=green]
                            >> (Also, the lines
                            >>
                            >> #ifndef FILE
                            >> #include <stdio.h>
                            >> #endif
                            >>
                            >> are suspicious; the #ifndef and #endif directives
                            >> are completely useless and irrelevant there.)[/color]
                            >
                            > I disagree with this claim too. There are two distinct methods of
                            > making use of this crc code as part of a system library. First, you
                            > may want to compile the crc code separately to generate an object
                            > file only and then make the object file available as part of your
                            > library while hiding the actual source code. Alternatively, you may
                            > want to make the actual source code available and have the user
                            > compile their source code and the crc source code together at once.
                            > To use the first method, you need to include "stdio.h" so the
                            > compiler will not complain about the type "FILE." But if include
                            > "stdio.h" without the preprocessor directives #ifndef and #endif,
                            > then you will run into a problem using the second method if your own
                            > source code file also includes "stdio.h."[/color]

                            No. Including stdio.h twice is harmless, and FILE may be a typedef, or
                            some sort of internal compiler magic, not a #define. As such, the #ifndef
                            is useless.
                            [color=blue]
                            > Since I cannot know in
                            > advance which method someone might use, I used the above method
                            > to let you to use either method without running into a problem.
                            > Having the #ifndef and #endif directives will not hurt you if your
                            > preferred method does not need them.[/color]

                            --
                            Freenet distribution not available
                            We were so poor we couldn't afford a watchdog. If we heard a noise at night,
                            we'd bark ourselves.
                            -- Crazy Jimmy

                            Comment

                            • bd

                              #15
                              Re: CRC32

                              On Fri, 01 Aug 2003 06:35:59 -0700, Glenn C. Rhoads wrote:
                              [color=blue]
                              > "Arthur J. O'Dwyer" <ajo@andrew.cmu .edu> wrote in message news:<Pine.LNX. 4.55L-032.03073116420 60.16782@unix46 .andrew.cmu.edu >...[color=green]
                              >> On Thu, 31 Jul 2003, Glenn C. Rhoads wrote:[color=darkred]
                              >>>
                              >>> "Carsten Hansen" <hansen.c@world net.att.net> wrote...
                              >>> > "Glenn C. Rhoads" <gcrhoads@yahoo .com> wrote in message[/color]
                              >> [I wrote:][color=darkred]
                              >>>>>> (Also, the lines
                              >>>>>>
                              >>>>>> #ifndef FILE
                              >>>>>> #include <stdio.h>
                              >>>>>> #endif
                              >>>>>>
                              >>>>>> are suspicious; the #ifndef and #endif directives
                              >>>>>> are completely useless and irrelevant there.)
                              >>>>>
                              >>>>> I disagree with this claim too.
                              >>>>
                              >>>> The problem with
                              >>>>>> #ifndef FILE
                              >>>>>> #include <stdio.h>
                              >>>>>> #endif
                              >>>> is that FILE is not a macro. Hence it is not defined during the
                              >>>> preprocessor stage of compilation, no matter whether <stdio.h> has
                              >>>> previously been included or not.
                              >>>
                              >>> Yes.
                              >>>
                              >>>> Moreover, the C standard explicitly allows a standard header to be
                              >>>> included multiple times "with no effect different from being included
                              >>>> only once". So, basically you have a wrong solution to a non-existing
                              >>>> problem.
                              >>>
                              >>> I guess you've never run into a traditional K&R compiler. With such
                              >>> a compiler, you cannot bring in header files more than once.[/color]
                              >>
                              >> As a matter of fact, since K&R C didn't use the standard headers, the
                              >> line #include <stdio.h> would probably cause a significant percentage
                              >> of pre-ANSI compiler to barf entirely. And, of course, no K&R C compiler
                              >> would get beyond
                              >>
                              >> void gen_table(void)
                              >>
                              >> without producing some *very* interesting error messages.[/color]
                              >
                              > Mine worked fine without a single error message.[/color]

                              Then you're not using a K&R C compiler, are you?
                              [color=blue][color=green][color=darkred]
                              >>> This
                              >>> code was written several years ago when the above was standard usage
                              >>> because back then, you could reasonably run into a K&R compiler and
                              >>> there is no other good way to do it on such a compiler. And it still
                              >>> works on a modern ansi-C compiler.[/color]
                              >>
                              >> Unfortunately, the "fix" now posted at
                              >> http://remus.rutgers.edu/~rhoads/Code/crc-32b.c
                              >> is even worse than the original.
                              >>
                              >> While the original #ifndef was valid, if silly and useless,
                              >> the new version reads
                              >>
                              >> #ifndef _PRINTF_H /* defined in stdio.h */
                              >> #include <stdio.h>
                              >> #endif
                              >>
                              >> which is absolutely ridiculous! No compiler will #define _PRINTF_H
                              >> for you,[/color]
                              >
                              > This is defined at the top of "stdio.h"[/color]

                              Maybe on your system. I just compiled:

                              #include <stdio.h>
                              #ifdef _PRINTF_H
                              #error _PRINTF_H defined
                              #else
                              #error _PRINTF_H not defined
                              #endif

                              And got:
                              foo.c:5:2: #error _PRINTF_H not defined
                              [color=blue]
                              > There are two c compilers available on the system I most commonly use,
                              > Sun's cc compiler and the Gnu-c compile (gcc). To double check, I just
                              > tested the above on both of them and it worked correctly. So much for
                              > the claim that no compiler will do this.[/color]

                              They don't. However, stdio.h may be #included more then once.
                              [color=blue][color=green]
                              >> and no user can safely #define _PRINTF_H for you, either,
                              >> because that identifier is "reserved for any use" by the Standard.
                              >>
                              >> I repeat, the correct C89 (ANSI C) solution is
                              >>
                              >> #include <stdio.h>[/color]
                              >
                              >
                              > And that doesn't work on every compiler I have access to
                              > (it does on Sun's cc compiler and the gnu-c compiler).[/color]

                              Which don't they work on?
                              [color=blue][color=green]
                              >> and the correct K&R solution is (a) to get rid of all those 'void'
                              >> keywords (and maybe that 'register unsigned long', although in the
                              >> absence of my K&R1 I'll let Dan or somebody handle that), and
                              >> (b) to let the client worry about it.
                              >>
                              >> -Arthur[/color]
                              >
                              > You are free to get rid of the #defines if you wish but I refuse
                              > to change what works on every compiler I have access to, to something
                              > that works on most but all of them.[/color]

                              --
                              Freenet distribution not available
                              BOFH Excuse #72:

                              Satan did it

                              Comment

                              Working...