You have a key represented in ASCII
that you’d like to convert into binary form. The
string containing the key is NULL
-terminated.
The code listed in the following
Section 4.4.3 parses an
ASCII string that represents hexadecimal data, and it returns a
malloc( )
‘d buffer of the
appropriate length. Note that the buffer will be half the size of the
input string, not counting the leading
“0x” if it exists. The exception is
when there is whitespace. This function passes back the number of
bytes written in its second parameter. If that parameter is negative,
an error occurred.
The spc_hex2bin( )
function shown in this section converts an
ASCII string into a binary string. Spaces and tabs are ignored. A
leading “0x” or
“0X” is ignored. There are two
cases in which this function can fail. First, if it sees a
non-hexadecimal digit, it assumes that the string is not in the right
format, and it returns NULL
, setting the error
parameter to ERR_NOT_HEX
. Second, if there is an
odd number of hex digits in the string, it returns
NULL
, setting the error parameter to
ERR_BAD_SIZE
.
#include <string.h> #include <stdlib.h> #include <ctype.h> #define ERR_NOT_HEX -1 #define ERR_BAD_SIZE -2 #define ERR_NO_MEM -3 unsigned char *spc_hex2bin(const unsigned char *input, size_t *l) { unsigned char shift = 4, value = 0; unsigned char *r, *ret; const unsigned char *p; if (!(r = ret = (unsigned char *)malloc(strlen(input) / 2))) { *l = ERR_NO_MEM; return 0; } for (p = input; isspace(*p); p++); if (p[0] = = '0' && (p[1] = = 'x' || p[1] = = 'X')) p += 2; while (p[0]) { switch (p[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': value |= (*p++ - '0') << shift; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': value |= (*p++ - 'a' + 0xa) << shift; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': value |= (*p++ - 'A' + 0xa) << shift; break; case 0: if (!shift) { *l = ERR_NOT_HEX; free(ret); return 0; } break; default: if (isspace(p[0])) p++; else { *l = ERR_NOT_HEX; free(ret); return 0; } } if ((shift = (shift + 4) % 8) != 0) { *r++ = value; value = 0; } } if (!shift) { *l = ERR_BAD_SIZE; free(ret); return 0; } *l = (r - ret); return (unsigned char *)realloc(ret, *l); }
Get Secure Programming Cookbook for C and C++ now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.