2 * This file is part of DisOrder
3 * Copyright (C) 2004, 2005, 2007, 2008 Richard Kettlewell
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 /** @file lib/hex.c @brief Hexadecimal encoding and decoding */
28 /** @brief Convert a byte sequence to hex
29 * @param ptr Pointer to first byte
30 * @param n Number of bytes
31 * @return Allocated string containing hexdump
33 char *hex(const uint8_t *ptr, size_t n) {
34 char *buf = xmalloc_noptr(n * 2 + 1), *p = buf;
37 p += sprintf(p, "%02x", (unsigned)*ptr++);
42 /** @brief Convert a character to its value as a hex digit
43 * @param c Character code
44 * @return Value has hex digit or -1
46 * The 'q' stands for 'quiet' - this function does not report errors.
48 int unhexdigitq(int c) {
60 case 'a': case 'A': return 10;
61 case 'b': case 'B': return 11;
62 case 'c': case 'C': return 12;
63 case 'd': case 'D': return 13;
64 case 'e': case 'E': return 14;
65 case 'f': case 'F': return 15;
70 /** @brief Convert a character to its value as a hex digit
71 * @param c Character code
72 * @return Value has hex digit or -1
74 * If the character is not a valid hex digit then an error is logged.
75 * See @ref unhexdigitq() if that is a problem.
77 int unhexdigit(int c) {
80 if((d = unhexdigitq(c)) < 0) error(0, "invalid hex digit");
84 /** @brief Convert a hex string to bytes
85 * @param s Pointer to hex string
86 * @param np Where to store byte string length or NULL
87 * @return Allocated buffer, or 0
89 * @p s should point to a 0-terminated string containing an even number
90 * of hex digits. They are converted to bytes and returned via the return
91 * value and optionally the length via @p np.
93 * On any error a message is logged and a null pointer is returned.
95 uint8_t *unhex(const char *s, size_t *np) {
100 if((l = strlen(s)) & 1) {
101 error(0, "hex string has odd length");
104 p = buf = xmalloc_noptr(l / 2);
106 if((d1 = unhexdigit(*s++)) < 0) return 0;
107 if((d2 = unhexdigit(*s++)) < 0) return 0;