Decoding a String – Solution

Encoding means nothing if you can’t decode, which is the task for this month’s Exercise: Transform the encoded hex bytes back into characters, unwinding the formula used to create them. The challenge isn’t really as much with coding the math as it is with translating hex bytes back into integer values — characters.

Being a filter, this Exercise’s solution runs as a loop. It consumes bytes until the `EOF` is encountered. For my version of the solution, I opted not to store the characters, but rather convert them one by one. The first character input is stored in int variable `a`, the second in int variable `b`:

```/* obtain first hex digit */
ch = getchar();
if( ch==EOF ) break;
a = hexdigit(ch);
if( a<0 ) break;

/* obtain second hex digit */
ch = getchar();
if( ch==EOF ) break;
b = hexdigit(ch);
if( b<0 ) break;```

Both blocks of code use the same sequence: read the character, check for the `EOF` and stop if so. Use the hexdigit() function to convert the character into a value. Check the value’s range, terminating the filter on an invalid hex digit.

Here is the hexdigit() function:

```/* return a hex digit integer value or
-1 for an invalid character */
int hexdigit(char c)
{
if( c>='A' && c<='F' )
return( c - 'A' + 10);
else if( c>='0' && c<='9' )
return(c - '0');
else
return(-1);
}```

The if comparison checks for uppercase hexadecimal letters, A through F. Lowercase letters aren't checked in that the encoding program generates only uppercase. When a letter is encountered, it's integer value is returned, 10 through 15.

The else if condition captures digits 0 through 9. These values are returned as their integer values, 0 through 9.

When both of these comparisons fail, the function returns -1, an error. This return is what's examined in the main() function, which terminates the filter program on the error.

To build the character, the main() function uses values stored in variables `a` and `b`:

```/* build a byte using the current hex
digit plus the previous digit in
byte */
byte += (a<<4) + b;
putchar(byte);```

The value of `a` shifted left four places and `b` retained. The result is the encoded value, which is added to the previous character output, stored in variable `byte`. Variable `byte` is initialized to zero, which is how the first character's ASCII value is output: as-is.