0

i'm trying to calculate the checksum of an array of ASCII hex values.

Say I have the following

char exArray[] = "3030422320303030373830434441453141542355";

It's 20 pairs of hex values that each represent an ASCII character (eg. 0x41 = A). How can I split them up to calculate a checksum?

Alternatively, how can I merge two values in an array to be one value? (eg. '4', '1' -> '41')

Kater
  • 63
  • 10
  • 3
    It seems to be a very bad example as there is non of `A` - `F` hex values in it. Can they occur? What did you try? – mch Sep 26 '18 at 07:06
  • 1
    First step would be converting the string representation (in hex) to an integer. – pmg Sep 26 '18 at 07:08
  • 1
    For the 2nd part, try `('4' - '0') * 16 + ('1' - '0')` – pmg Sep 26 '18 at 07:09
  • @mch Yes they can. And I tried to iterate through the array and save two characters to a new object, but that way I end up with two individual characters still. – Kater Sep 26 '18 at 07:23
  • @pmg Thanks for the suggestion, I'll try that! – Kater Sep 26 '18 at 07:28
  • 1
    Are you sure the array is of type `uint16_t`? It looks lake a `char` array. It generates a compiler error. – Weather Vane Sep 26 '18 at 07:28
  • @WeatherVane Yes sorry, I wrote it down wrong. In my code it is of course a `char` array. – Kater Sep 26 '18 at 09:14

2 Answers2

2

@pmg:

First step would be converting the string representation (in hex) to an integer.

For the 2nd part, try ('4' - '0') * 16 + ('1' - '0')

This ultimately did the trick, love how simple it is too,

My implementation now looks somewhat like this.

uint8_t t = 0, tem, tem2, sum;
uint32_t chksum = 0;

void checkSum(void)
{
    while (t < 40)
    {
        asciiToDec(exArray[t]);
        tem = global.DezAscii[0];
        t++;
        asciiToDec(exArray[t]);
        tem2 = global.DezAscii[0];
        t++;

        sum = (tem) * 16 + (tem2);
        chksum += sum;
    }
}

void asciiToDec(uint8_t value)
{
    if (value == 'A')
        global.DezAscii[0] = 10;
    else if (value == 'B')
        global.DezAscii[0] = 11;
    else if (value == 'C')
        global.DezAscii[0] = 12;
    else if (value == 'D')
        global.DezAscii[0] = 13;
    else if (value == 'E')
        global.DezAscii[0] = 14;
    else if (value == 'F')
        global.DezAscii[0] = 15;
    else
        global.DezAscii[0] = value;
}
Kater
  • 63
  • 10
1
uint16_t exArray[] = "3030422320303030373830434441453141542355";

I don't think this does what you are trying to do. The string literal is treated as a pointer to a const char. It's not even compiling for me. What you want here is something like this:

const char * exArray = "3030422320303030373830434441453141542355";

It's 20 pairs of hex values that each represent an ASCII character (eg. 0x41 = A). How can I split them up to calculate a checksum?

You could loop through the array, doing what you want to do with the two chars inside the loop:

for (int i = 0; exArray[i]; i+=2) {
    printf("my chars are %c and %c\n", exArray[i], exArray[i+1]);
    // do the calculations you need here using exArray[i] and exArray[i+1]
}

Alternatively, how can I merge two values in an array to be one value? (eg. '4', '1' -> '41')

I'm not sure what you mean here. Do you mean "41", as in the string representing 41? To do that, allocate three chars, then copy over those two chars and a null terminator. Something like

char hexByte[3];
hexByte[2] = 0; // setting the null terminator
for (int i = 0; exArray[i]; i+=2) {
    hexByte[0] = exArray[i];
    hexByte[1] = exArray[i+1];
    printf("the string \"hexByte\" is: %s\n", hexByte);
    // do something with hexByte here
}

If you want to convert it to its integer representation, use strtol:

printf("int value: %ld\n", strtol(hexByte, 0, 16));
Blaze
  • 16,736
  • 2
  • 25
  • 44
  • Yea in my code it's a char array too, I wrote it down incorrectly for the example. Anyway, thanks for the suggestion, I will try that one too, but for now @pmg solution works. – Kater Sep 26 '18 at 09:16