| 464 *data = out; |
464 *data = out; |
| 465 if (size) |
465 if (size) |
| 466 *size = len; |
466 *size = len; |
| 467 } |
467 } |
| 468 |
468 |
| |
469 /* |
| |
470 * Converts raw data to a pretty, null-terminated base16 string. |
| |
471 */ |
| |
472 char *tobase16(const char *data, int length) |
| |
473 { |
| |
474 int i; |
| |
475 char *ascii = NULL; |
| |
476 |
| |
477 if (!data || !length) |
| |
478 return NULL; |
| |
479 |
| |
480 ascii = (char *)malloc(length*2 + 1); |
| |
481 |
| |
482 for (i=0; i<length; i++) |
| |
483 snprintf(&ascii[i*2], 3, "%02hhx", data[i]); |
| |
484 |
| |
485 return ascii; |
| |
486 } |
| |
487 |
| |
488 /* |
| |
489 * Converts a null-terminated string of hexidecimal to raw data. |
| |
490 */ |
| |
491 int frombase16(const char *ascii, char **raw) |
| |
492 { |
| |
493 int len, i, accumulator; |
| |
494 char *data; |
| |
495 |
| |
496 if (!ascii || !(len = strlen(ascii)) || (len % 2)) |
| |
497 return 0; |
| |
498 |
| |
499 data = (char *)malloc((len/2)*sizeof(char)); |
| |
500 for (i=0; i<len; i++) { |
| |
501 if (!(i % 2)) |
| |
502 accumulator = 0; |
| |
503 else |
| |
504 accumulator = accumulator << 4; |
| |
505 if (isdigit(ascii[i])) |
| |
506 accumulator |= ascii[i]-48; |
| |
507 else switch(ascii[i]) { |
| |
508 case 'a': case 'A': accumulator|=10; break; |
| |
509 case 'b': case 'B': accumulator|=11; break; |
| |
510 case 'c': case 'C': accumulator|=12; break; |
| |
511 case 'd': case 'D': accumulator|=13; break; |
| |
512 case 'e': case 'E': accumulator|=14; break; |
| |
513 case 'f': case 'F': accumulator|=15; break; |
| |
514 } |
| |
515 if (i % 2) |
| |
516 data[(i-1)/2] = accumulator; |
| |
517 } |
| |
518 |
| |
519 *raw = data; |
| |
520 return len/2; |
| |
521 } |
| 469 |
522 |
| 470 char *normalize(const char *s) |
523 char *normalize(const char *s) |
| 471 { |
524 { |
| 472 static char buf[BUF_LEN]; |
525 static char buf[BUF_LEN]; |
| 473 char *tmp; |
526 char *tmp; |