Ejemplo n.º 1
0
int hex2bin(char *hex, unsigned char *bin) {
  unsigned int i = 0;
  unsigned int j = 0;

  /* Trim string if comments present */
  if (strchr(hex, '#') != NULL)
    *strchr(hex, '#') = 0;
  if (strchr(hex, '*') != NULL)
    *strchr(hex, '*') = 0;
  if (strchr(hex, '\'') != NULL)
    *strchr(hex, '\'') = 0;

  for (i = 0; i < strlen(hex); i++) {
    if (hex[i] >= '0' && unhex(hex[i]) < 0){
      printf("Bad hex digit encountered.\n"); 
      return( -1 );
    }
  }

  for (i = 0; i < strlen(hex); i++) {
    if (hex[i] < '0')
      continue;
    if (hex[i] >= '0' && hex[i+1] >= '0') {
      bin[j++] = unhex(hex[i])*16+unhex(hex[i+1]);
      i++;
      continue;
    }
    if (hex[i] >= '0') {
      bin[j++] = unhex(hex[i]);
    }
  }
  return (j);
}
Ejemplo n.º 2
0
/*
 * Decodes a string in RFC 3986 percent-encoded representation.
 */
int
percent_decode(const char *in, size_t ilen, char *out, size_t *olen)
{
	size_t len;

	for (len = 0; ilen && *in; --ilen, ++in) {
		if (*in != '%') {
			if (++len < *olen)
				*out++ = *in;
		} else if (ilen >= 3 && is_xdigit(in[1]) && is_xdigit(in[2])) {
			if (++len < *olen)
				*out++ = unhex(in[1]) << 4 | unhex(in[2]);
			in += 2;
		} else {
			errno = EINVAL;
			return (-1);
		}
	}
	if (len < *olen)
		*out = '\0';
	if (len >= *olen) {
		/* overflow */
		*olen = len;
		errno = ENOSPC;
		return (-1);
	}
	*olen = len;
	return (0);
}
Ejemplo n.º 3
0
char *unhex_in_place(char *str)
{
  char *dest = strchr(str, '%');

  if (dest) {
    str = dest;
    while (*str) {
      if (*str == '%' && isxdigit(str[1]) && isxdigit(str[2])) {
        //printf("[%s:%d] cannot portably compute sscanf %%2hhx\n", __FILE__, __LINE__);
        //abort();
        *dest = unhex(str[1])*16 + unhex(str[2]);
        ++dest;
    	//sscanf(str + 1, FMT_HEX_CHAR, dest++);
	str += 3;
      } else {
	*dest++ = *str++;
      }
    }

    *dest = '\0';
    return dest;
  } else {
    return str + strlen(str);
  }
}
char	*xs_decode(char *dst, char *src) {
	char	*save = dst;
	register	char	c, t;

	for(;t = *src++;) {
		if(t == '+') {
			*dst++ = ' ';
		} else if(t == '%') {
			t = *src++;
			c = unhex(t) * 0x10;
			if(c == -1) {
				return NULL;
			}
			t = *src++;
			c += unhex(t);
			if(c == -1) {
				return NULL;
			}
			*dst++ = c;
		} else {
			*dst++ = t;
		}
	}
	*dst='\0';
	return save;
}
Ejemplo n.º 5
0
static int
next_ahxd(fz_stream *stm, int max)
{
	fz_ahxd *state = stm->state;
	unsigned char *p = state->buffer;
	unsigned char *ep;
	int a, b, c, odd;

	if (max > sizeof(state->buffer))
		max = sizeof(state->buffer);
	ep = p + max;

	odd = 0;

	while (p < ep)
	{
		if (state->eod)
			break;

		c = fz_read_byte(state->chain);
		if (c < 0)
			break;

		if (ishex(c))
		{
			if (!odd)
			{
				a = unhex(c);
				odd = 1;
			}
			else
			{
				b = unhex(c);
				*p++ = (a << 4) | b;
				odd = 0;
			}
		}
		else if (c == '>')
		{
			if (odd)
				*p++ = (a << 4);
			state->eod = 1;
			break;
		}
		else if (!iswhite(c))
		{
			fz_throw(stm->ctx, FZ_ERROR_GENERIC, "bad data in ahxd: '%c'", c);
		}
	}
	stm->rp = state->buffer;
	stm->wp = p;
	stm->pos += p - state->buffer;

	if (stm->rp != p)
		return *stm->rp++;
	return EOF;
}
Ejemplo n.º 6
0
static void str2bin(byte*tgt,const char*str,int len)
{
	int i;
	char s[1024];
	if(strlen(str)<(len*2)){
		for(i=0;i<len*2;i++)s[i]='0';
		strcpy(s+(len*2-strlen(str)),str);
	}else strcpy(s,str);
	for(i=0;i<len;i++){
		tgt[i]=(unhex(s[i*2])<<4) | unhex(s[i*2+1]);
	}
}
Ejemplo n.º 7
0
void
unhexrow(char *raw, char *hex)
{
	int a, b;
	while (hex[0] && hex[1])
	{
		a = hex[0];
		b = hex[1];
		hex += 2;
		*raw++ = unhex(a) * 16 + unhex(b);
	}
	*raw = 0;
}
Ejemplo n.º 8
0
static bool unescape(const std::string& s,int mode,std::string& out) {
	int n = 0;
	bool hasPlus = false;
	for(unsigned i=0;i<s.size();) {
		if(s[i] == '%'){
			n++;
			if( i+2 >= s.size() || !ishex(s[i+1]) || !ishex(s[i+2]) ) {
				std::string tmp = s.substr(i);
				if (tmp.size() > 3) {
					tmp = tmp.substr(0,3);
				}
				return false;
			}
			i += 3;
		}else if( s[i] == '+'){
			hasPlus = mode == encodeQueryComponent;
			i++;
		}else{
			i++;
		}
	}

	if( n == 0 && !hasPlus) {
		out = s;
		return true;
	}
	std::string myout;
	myout.resize(s.size() - 2*n);
	int j=0;
	for(unsigned i=0;i<s.size();) {
		if(s[i] == '%'){
			myout[j] = unhex(s[i+1])<<4 | unhex(s[i+2]);
			j++;
			i += 3;
		}else if(s[i] == '+'){
			if (mode == encodeQueryComponent) {
				myout[j] = ' ';
			} else {
				myout[j] = '+';
			}
			j++;
			i++;
		}else{
			myout[j] = s[i];
			j++;
			i++;
		}
	}
	out = myout;
	return true;
}
Ejemplo n.º 9
0
int
_decqp(uchar *out, int lim, char *in, int n, int underscores)
{
	char *p, *ep;
	uchar *eout, *out0;
	
	out0 = out;
	eout = out+lim;
	for(p=in, ep=in+n; p<ep && out<eout; ){
		if(underscores && *p == '_'){
			*out++ = ' ';
			p++;
		}
		else if(*p == '='){
			if(p+1 >= ep)
				break;
			if(*(p+1) == '\n'){
				p += 2;
				continue;
			}
			if(p+3 > ep)
				break;
			*out++ = unhex(p+1);
			p += 3;
		}else
			*out++ = *p++;
	}
	return out-out0;
}
Ejemplo n.º 10
0
static void set_banner(struct openconnect_info *vpninfo)
{
	char *banner, *legacy_banner, *q;
	const char *p;

	if (!vpninfo->banner || !(banner = malloc(strlen(vpninfo->banner)+1))) {
		script_setenv(vpninfo, "CISCO_BANNER", NULL, 0);
		return;
	}
	p = vpninfo->banner;
	q = banner;

	while (*p) {
		if (*p == '%' && isxdigit((int)(unsigned char)p[1]) &&
		    isxdigit((int)(unsigned char)p[2])) {
			*(q++) = unhex(p + 1);
			p += 3;
		} else
			*(q++) = *(p++);
	}
	*q = 0;
	legacy_banner = openconnect_utf8_to_legacy(vpninfo, banner);
	script_setenv(vpninfo, "CISCO_BANNER", legacy_banner, 0);
	if (legacy_banner != banner)
		free(legacy_banner);

	free(banner);
}
Ejemplo n.º 11
0
static int hexpass2hash160(unsigned char *hpass, size_t hpass_sz) {
  if (hpass_sz / 2 > unhexed_sz) {
    unhexed_sz = hpass_sz * 3;
    unhexed = chkrealloc(unhexed, unhexed_sz);
  }
  return pass2hash160(unhex(hpass, hpass_sz, unhexed, unhexed_sz), hpass_sz>>1);
}
Ejemplo n.º 12
0
static int
read_ahxd(fz_stream *stm, unsigned char *buf, int len)
{
	fz_ahxd *state = stm->state;
	unsigned char *p = buf;
	unsigned char *ep = buf + len;
	int a, b, c, odd;

	odd = 0;

	while (p < ep)
	{
		if (state->eod)
			return p - buf;

		c = fz_read_byte(state->chain);
		if (c < 0)
			return p - buf;

		if (ishex(c))
		{
			if (!odd)
			{
				a = unhex(c);
				odd = 1;
			}
			else
			{
				b = unhex(c);
				*p++ = (a << 4) | b;
				odd = 0;
			}
		}
		else if (c == '>')
		{
			if (odd)
				*p++ = (a << 4);
			state->eod = 1;
		}
		else if (!iswhite(c))
		{
			fz_throw(stm->ctx, "bad data in ahxd: '%c'", c);
		}
	}

	return p - buf;
}
Ejemplo n.º 13
0
int
hexparse(char *hex, uchar *dat, int ndat)
{
	int i, n;

	n = strlen(hex);
	if(n%2)
		return -1;
	n /= 2;
	if(n > ndat)
		return -1;
	if(hex[strspn(hex, "0123456789abcdefABCDEF")] != '\0')
		return -1;
	for(i=0; i<n; i++)
		dat[i] = (unhex(hex[2*i])<<4)|unhex(hex[2*i+1]);
	return n;
}
Ejemplo n.º 14
0
 bool
 parse_hex(Iter& it, Unsigned& v)
 {
     unsigned char d;
     if(! unhex(d, *it))
         return false;
     v = d;
     for(;;)
     {
         if(! unhex(d, *++it))
             break;
         auto const v0 = v;
         v = 16 * v + d;
         if(v < v0)
             return false;
     }
     return true;
 }
Ejemplo n.º 15
0
static void check(const char *rstr, const char *sstr,
                  const char *msgstr, const char *tagstr)
{
  uint8_t r[16], s[16], tag[16];
  uint8_t msg[132], out[16];

  unhex(r, sizeof r, rstr);
  unhex(s, sizeof s, sstr);
  size_t nmsg = unhex(msg, sizeof msg, msgstr);
  unhex(tag, sizeof tag, tagstr);

  cf_poly1305 ctx;
  cf_poly1305_init(&ctx, r, s);
  cf_poly1305_update(&ctx, msg, nmsg);
  cf_poly1305_finish(&ctx, out);

  TEST_CHECK(memcmp(out, tag, 16) == 0);
}
Ejemplo n.º 16
0
static void convert_passwd(char *buf, char *newpwd, const int keyfd)
{
    uint8_t key[HEXPASSWDLEN];
    Key_schedule schedule;
    unsigned int i, j;

    if (!newpwd) {
        /* convert to binary */
        for (i = j = 0; i < sizeof(key); i += 2, j++)
            buf[j] = (unhex(buf[i]) << 4) | unhex(buf[i + 1]);
        if (j <= DES_KEY_SZ)
            memset(buf + j, 0, sizeof(key) - j);
    }

    if (keyfd > -1) {
        lseek(keyfd, 0, SEEK_SET);
        read(keyfd, key, sizeof(key));
        /* convert to binary */
        for (i = j = 0; i < sizeof(key); i += 2, j++)
            key[j] = (unhex(key[i]) << 4) | unhex(key[i + 1]);
        if (j <= DES_KEY_SZ)
            memset(key + j, 0, sizeof(key) - j);
        key_sched((C_Block *) key, schedule);
        memset(key, 0, sizeof(key));
        if (newpwd) {
            ecb_encrypt((C_Block *) newpwd, (C_Block *) newpwd, schedule,
                        DES_ENCRYPT);
        } else {
            /* decrypt the password */
            ecb_encrypt((C_Block *) buf, (C_Block *) buf, schedule, DES_DECRYPT);
        }
        memset(&schedule, 0, sizeof(schedule));
    }

    if (newpwd) {
        const unsigned char hextable[] = "0123456789ABCDEF";

        /* convert to hex */
        for (i = j = 0; i < DES_KEY_SZ; i++, j += 2) {
            buf[j] = hextable[(newpwd[i] & 0xF0) >> 4];
            buf[j + 1] = hextable[newpwd[i] & 0x0F];
        }
    }
}
Ejemplo n.º 17
0
static char *_GetParam(pThreadData ThisThread,
                     char *key){
  char *s;
  int i,j;

  if( ! ThisThread->getparams[0] ){
    /* when first called it contains no data */
    s = ThisThread->pszQueryString;
    while( *s && *s != '?' )s++;
    if( ! *s )return NULL;
    s++; /* step over the ? */
    /* check the size before copiing */
    ThisThread->getparlen = strlen(s);
    if( ThisThread->getparlen >= MAX_QUERY_LENGTH )return NULL;
    strcpy(ThisThread->getparams,s);
    s = ThisThread->getparams;
    for( i=j=0 ; ; i++ ){
       s[i] = s[j];
       if( ! s[j] )break;
       if( s[j] == '%' && s[j+1] && s[j+2] ){
         s[i] = unhex(s[j+1])*16+unhex(s[j+2]);
         j += 3;
         }else j++;
       }
    ThisThread->getparlen = i;
    s = ThisThread->getparams;
    while( *s ){
      if( *s == '&' )*s = (char)0;
      s++;
      }
    }
  /* Now we have the get params in ThisThread->getparams */
  s = ThisThread->getparams;
  for( i = 0 ; i < ThisThread->getparlen ; i++ ){
    for( j = 0 ; key[j] && s[i] && s[i] != '=' ; j++, i++ ){
      if( s[i] != key[j] ){
        while( s[i] )i++;
        break;
        }
      }
    if( s[i] )return s+i+1;
    }
  return NULL;
  }
Ejemplo n.º 18
0
static int
lex_hex_string(fz_stream *f, pdf_lexbuf *lb)
{
	char *s = lb->scratch;
	char *e = s + lb->size;
	int a = 0, x = 0;
	int c;

	while (1)
	{
		if (s == e)
		{
			s += pdf_lexbuf_grow(lb);
			e = lb->scratch + lb->size;
		}
		c = fz_read_byte(f);
		switch (c)
		{
		case IS_WHITE:
			break;
		case IS_HEX:
			if (x)
			{
				*s++ = a * 16 + unhex(c);
				x = !x;
			}
			else
			{
				a = unhex(c);
				x = !x;
			}
			break;
		case '>':
		case EOF:
			goto end;
		default:
			fz_warn(f->ctx, "ignoring invalid character in hex string");
		}
	}
end:
	lb->len = s - lb->scratch;
	return PDF_TOK_STRING;
}
Ejemplo n.º 19
0
/*
 * Remove URL hex escapes from s... done in place.  The basic concept for
 * this routine is borrowed from the WWW library HTUnEscape() routine.
 *
 * A similar function called nsldapi_hex_unescape can be found in
 * ../../libraries/libldap/unescape.c
 */
static void
hex_unescape( char *s )
{
	char	*p;

	for ( p = s; *s != '\0'; ++s ) {
		if ( *s == '%' ) {
			if ( *++s != '\0' ) {
				*p = unhex( *s ) << 4;
			}
			if ( *++s != '\0' ) {
				*p++ += unhex( *s );
			}
		} else {
			*p++ = *s;
		}
	}

	*p = '\0';
}
Ejemplo n.º 20
0
static char *
ascii2hex(char *anHexaStr, int *aResLen)
{
	int theLen = 0;
	char *theRes = malloc(strlen(anHexaStr) /2 + 1);

	if (theRes == NULL)
		return (NULL);
	while (isxdigit(*anHexaStr)) {
		theRes[theLen] = unhex(*anHexaStr) << 4;
		if (++anHexaStr != '\0') {
			theRes[theLen] += unhex(*anHexaStr);
			anHexaStr++;
		}
		theLen++;
	}
	theRes[theLen] = '\0';
	*aResLen = theLen;
	return (theRes);
}
Ejemplo n.º 21
0
size_t scgi_urldecode(char *enc) {
    char *dec, *p;

    if (enc == NULL) {
        return(0);
    }

    dec = enc;
    for (p = enc; *p; p++, dec++) {
        if (*p == '+') {
            *dec = ' ';
        } else if (*p == '%') {
            *dec = (char)((unhex(*(p + 1)) << 4) + unhex(*(p + 2)));
            p += 2;
        } else {
            *dec = *p;
        }
    }
    *dec = '\0';
    return((size_t)(dec - enc));
}
Ejemplo n.º 22
0
/*
 * Some fonts in XPS are obfuscated by XOR:ing the first 32 bytes of the
 * data with the GUID in the fontname.
 */
static void
xps_deobfuscate_font_resource(fz_context *ctx, xps_document *doc, xps_part *part)
{
    unsigned char buf[33];
    unsigned char key[16];
    char *p;
    int i;

    if (part->size < 32)
    {
        fz_warn(ctx, "insufficient data for font deobfuscation");
        return;
    }

    p = strrchr(part->name, '/');
    if (!p)
        p = part->name;

    for (i = 0; i < 32 && *p; p++)
    {
        if (ishex(*p))
            buf[i++] = *p;
    }
    buf[i] = 0;

    if (i != 32)
    {
        fz_warn(ctx, "cannot extract GUID from obfuscated font part name");
        return;
    }

    for (i = 0; i < 16; i++)
        key[i] = unhex(buf[i*2+0]) * 16 + unhex(buf[i*2+1]);

    for (i = 0; i < 16; i++)
    {
        part->data[i] ^= key[15-i];
        part->data[i+16] ^= key[15-i];
    }
}
Ejemplo n.º 23
0
ulng color_in_range(char *clow, char *chigh, int percent) {
    int a_s = strlen(clow);
    int b_s = strlen(chigh);
    if (a_s != 7 || b_s != 7) {
        puts("color range must be in the form #XXXXXX:#XXXXXX");
        exit(1);
    }
    char *res = calloc(sizeof(char), a_s);
    res[0] = '#';
    
    uint8_t a_red = 16*hex(clow[1])+hex(clow[2]);
    uint8_t a_grn = 16*hex(clow[3])+hex(clow[4]);
    uint8_t a_blu = 16*hex(clow[5])+hex(clow[6]);

    uint8_t b_red = 16*hex(chigh[1])+hex(chigh[2]);
    uint8_t b_grn = 16*hex(chigh[3])+hex(chigh[4]);
    uint8_t b_blu = 16*hex(chigh[5])+hex(chigh[6]);

    uint8_t n_red = a_red + ((b_red-a_red)*percent)/100;
    uint8_t n_grn = a_grn + ((b_grn-a_grn)*percent)/100;
    uint8_t n_blu = a_blu + ((b_blu-a_blu)*percent)/100;

    res[1] = unhex(n_red/16);
    res[2] = unhex(n_red%16);
    res[3] = unhex(n_grn/16);
    res[4] = unhex(n_grn%16);
    res[5] = unhex(n_blu/16);
    res[6] = unhex(n_blu%16);

    ulng result = getcolor(res);
    free(res);
    return result;
}
Ejemplo n.º 24
0
char charVal(char *s)
/* Return hexadecimal or literal decoding of string into char. */
{
int len = strlen(s);
if (len == 1)
   return s[0];
else if (len == 2)
   return unhex(s);
else
   {
   usage();
   return 0;
   }
}
Ejemplo n.º 25
0
static int
lex_hex_string(fz_stream *f, char *buf, int n)
{
	char *s = buf;
	char *e = buf + n;
	int a = 0, x = 0;
	int c;

	while (s < e)
	{
		c = fz_read_byte(f);
		switch (c)
		{
		case IS_WHITE:
			break;
		case IS_HEX:
			if (x)
			{
				*s++ = a * 16 + unhex(c);
				x = !x;
			}
			else
			{
				a = unhex(c);
				x = !x;
			}
			break;
		case '>':
		case EOF:
			goto end;
		default:
			fz_warn("ignoring invalid character in hex string: '%c'", c);
		}
	}
end:
	return s - buf;
}
Ejemplo n.º 26
0
string unhex(string str, const string &delim)
{
    if (!delim.empty())
    {
        CharSet d(delim);
        int l = 0;
        for (int i = 0; i < str.length(); ++i)
            if (!d.exists(str[i]))
                str[l++] = str[i];
        str.resize(l);
    }
    string res;
    if (str.length() % 2 != 0)
        throw InvalidHexStringException(Utils::Strings::format("invalid hex string %s", str.c_str()));
    for (int i = 0; i < str.length(); i += 2)
    {
        int h = unhex(str[i]);
        int l = unhex(str[i + 1]);
        if (h == -1 || l == -1)
            throw InvalidHexStringException(Utils::Strings::format("invalid hex string %s", str.c_str()));
        res += static_cast<char>((h << 4) + l);
    }
    return res;
}
Ejemplo n.º 27
0
int main(int argc, char **argv) {
  int ret;
  hash160_t hash;
  char *line = NULL;
  size_t line_sz = 0;
  unsigned char buf[128];
  unsigned char *bloom, *bloomfile, *hashfile;
  FILE *ifile = stdin, *ofile = stdout, *hfile = NULL;
  mmapf_ctx bloom_mmapf;

  if (argc < 2 || argc > 3) {
    fprintf(stderr, "Usage: %s BLOOM_FILTER_FILE HASH_FILE\n", argv[0]);
    return 1;
  }

  bloomfile = argv[1];

  if ((ret = mmapf(&bloom_mmapf, bloomfile, BLOOM_SIZE, MMAPF_RNDRD)) != MMAPF_OKAY) {
    fprintf(stderr, "failed to open bloom filter '%s': %s\n", bloomfile, mmapf_strerror(ret));
    return 1;
  } else if (bloom_mmapf.mem == NULL) {
    fprintf(stderr, "got NULL pointer trying to set up bloom filter\n");
    return 1;
  }

  bloom = bloom_mmapf.mem;

  if (argc == 3) {
    hashfile = argv[2];
    hfile = fopen(hashfile, "r");
  }

  while (getline(&line, &line_sz, ifile) > 0) {
    unhex(line, strlen(line), hash.uc, sizeof(hash.uc)); 
    if (bloom_chk_hash160(bloom, hash.ul)) {
      if (hfile && !hsearchf(hfile, &hash)) {
        //fprintf(ofile, "%s (false positive)\n", hex(hash.uc, sizeof(hash.uc), buf, sizeof(buf)));
        continue;
      }
      //fprintf(ofile, "%s\n", hex(hash.uc, sizeof(hash.uc), buf, sizeof(buf)));
      fprintf(ofile, "%s", line);
    }
  }

  return 0;
}
Ejemplo n.º 28
0
/** decode urlencoded URL into ascii characters
 * if dest is NULL, return malloc()'d string. needs to be free()'d
 * if src_len is negative treat src as null terminated
 * return:
 * 	0 on error (overflow of dest, allocation failure)
 *  dest or allocated pointer on success
 */
char *uri_unescape(char *dest, size_t dest_len, const char *src, int src_len)
{
	assert(src!=NULL);
	char *ret;
	int ret_is_allocated;
	assert(src!=NULL);
	if(src_len<0) {
		src_len=strlen((const char *)src);
	}
	ret_is_allocated=!dest;
	if(ret_is_allocated) {
		dest_len=src_len+1; /* TODO: calculate the exact needed size? */
		dest=(char*)malloc(dest_len);
		if(!dest) {
			return 0; /* allocation failure */
		}
	}
	ret=dest;
	for(;dest_len>1 && src_len>0;dest_len--,dest++) {
		if(*src=='%' && src_len>=3 && ishex(src+1)) {
			*dest=(char)unhex(src+1);
			src+=3;
			src_len-=3;
		} else if(*src=='+') {
			*dest=' ';
			src++;
			src_len--;
		} else {
			*dest=*(src++);
			src_len--;
		}
	}
	/* check for errors - src was not fully consumed */
	if(src_len!=0) {
		if(ret_is_allocated) {
			free(ret);
		}
		return 0;
	}
	assert(dest_len>=1);
	*dest=0;

	return ret;
}
Ejemplo n.º 29
0
void doIt(char *ch, int fileCount, char *fileNames[])
/* doIt - Count the number of occurences of a particular char. */
{
char c;
int i;
char *fileName;

if (strlen(ch) > 1)
   c = unhex(ch);
else
   c = ch[0];
for (i=0; i<fileCount; ++i)
    {
    int count;
    fileName = fileNames[i];
    count = countCharsInFile(c, fileName);
    if (count > 0)
       printf("%s %d\n", fileName, count);
    }
}
Ejemplo n.º 30
0
void CommonTestsSuite::test_unhex() {
	string hexString;
	string bin;

	hexString = "";
	bin = unhex(hexString);
	TS_ASSERT(bin == "");

	hexString = "1";
	bin = unhex(hexString);
	TS_ASSERT(bin == "");

	hexString = "1non_permitted_characters";
	bin = unhex(hexString);
	TS_ASSERT(bin == "");

	hexString = "1non_permitted_characters1";
	bin = unhex(hexString);
	TS_ASSERT(bin == "");

	for (uint32_t i = 0; i <= 255; i++) {
		hexString = format("%02x", i);
		bin = unhex(hexString);
		TS_ASSERT(bin.length() == 1);
		TS_ASSERT((uint8_t) bin[0] == i);
	}

	for (uint32_t i = 1; i <= 255; i++) {
		hexString = "";
		for (uint32_t j = 0; j < i; j++) {
			hexString += format("%02x", j);
		}
		bin = unhex(hexString);
		if (bin.length() != i) {
			TS_ASSERT(bin.length() == i);
		}
		for (uint32_t j = 0; j < i; j++) {
			if ((uint8_t) bin[j] != j) {
				TS_ASSERT((uint8_t) bin[j] == j);
			}
		}
	}
}