I have a unsigned char array of which I'd like to calculate the CRC32 checksum.
The CRC32 function also expects a unsigned char pointer, however, it interprets the array as an ASCII array.
This is the CRC function:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned int crc32(unsigned char *message) 
{
   int i, j;
   unsigned int byte, crc, mask;
   i = 0;
   crc = 0xFFFFFFFF;
   while (message[i] != 0) {
      byte = message[i];            // Get next byte.
      crc = crc ^ byte;
      for (j = 7; j >= 0; j--) {    // Do eight times.
         mask = -(crc & 1);
         crc = (crc >> 1) ^ (0xEDB88320 & mask);
      }
      i = i + 1;
   }
   return ~crc;
}
int main(int argc, char **argv)
{
    unsigned char *arr;
    if ((arr = malloc(64)) == NULL) {
        perror("Could not allocate memory");
        exit(EXIT_FAILURE);
    }
    char str[] = "47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000";
    memcpy(arr, str, strlen(str));
    // ...
    unsigned int crc = crc32(arr);
    printf("CRC: 0x%x\n", crc); // 0xB6BA014A instead of 0xBF6B57A2
    return 0;
}
Now, I'd like to calculate the CRC32 but the unsigned char array has to be interpreted as an hex array.
F.ex., this is the result of the calculated CRC: 
Input:
"47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000"
How to interpret an unsigned char array as hex array?
Convert each pair of hexadecimal characters in the string to a byte value.  Code below converts via a compound literal to form a 3 byte string, followed by a call to strtoul(). 
//                    v----------------------------------v _compound literal_
arr2[i / 2] = strtoul((char[3]) {str[i], str[i + 1], '\0'}, 0, 16);
More advanced code would test for the unexpected presence of non-hexadecimal characters or an odd/zero length.
CRC calculation changes needed
Change CRC calculation to a length based one rather than a string one.
// unsigned int crc32(const char *)
unsigned int crc32(const void *m, size_t len)
Although not coded below, consider uint32_t instead of unsigned int in crc32() for correct operation when unsigned is not 32-bit.
Altogether
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned int crc32(const void *m, size_t len) {
  const unsigned char *message = m;
  size_t i;
  int j;
  unsigned int byte, crc, mask;
  i = 0;
  crc = 0xFFFFFFFF;
  //while (message[i] != 0) {
  while (i < len) {
    byte = message[i];            // Get next byte.
    crc = crc ^ byte;
    for (j = 7; j >= 0; j--) {    // Do eight times.
      mask = -(crc & 1);
      crc = (crc >> 1) ^ (0xEDB88320 & mask);
    }
    i = i + 1;
  }
  return ~crc;
}
Sample usage
int main() {
  char str[] =
      "47d46d17e759a1dec810758c08004510002127d90000401152e4c0a8b21fc0a8b2255b9b5b9c000db20caabbccddee00000000000000000000000000";
  size_t len = strlen(str);
  unsigned int crc = crc32(str, len);
  printf("CRC: 0x%X\n", crc); // 0xB6BA014A instead of 0xBF6B57A2
  size_t len2 = (len + 1) / 2;
  unsigned char arr2[len2];
  for (size_t i = 0; i < len; i += 2) {
    arr2[i / 2] = strtoul((char[3]) {str[i], str[i + 1], '\0'}, 0, 16);
  }
  crc = crc32(arr2, len2);
  printf("CRC: 0x%X\n", crc); // 0xB6BA014A instead of 0xBF6B57A2
  return 0;
}
Output
CRC: 0xB6BA014A
CRC: 0xBF6B57A2
OP original code had undefined behavior in that it looked for a null character with while (message[i] != 0) {, yet memcpy(arr, str, strlen(str)); failed to provide one.
 chux - Reinstate Monica • edited Dec 1, 2018 by
 chux - Reinstate Monica • edited Dec 1, 2018 by  chux - Reinstate Monica
 chux - Reinstate MonicaUser contributions licensed under CC BY-SA 3.0