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.

Click here to view my full solution at Github.

I hope your solution met with success. My first solution tried to read both hex digits at the same time, converting them to a single byte value. Only when I decided to read the characters one at a time did the solution finally occur to me. It made the hexdigit() function easier to code.

Leave a Reply