2 * This file is part of DisOrder
3 * Copyright (C) 2004, 2005 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 */
32 /** @brief Convert a byte sequence to hex
33 * @param ptr Pointer to first byte
34 * @param n Number of bytes
35 * @return Allocated string containing hexdump
37 char *hex(const uint8_t *ptr, size_t n) {
38 char *buf = xmalloc_noptr(n * 2 + 1), *p = buf;
41 p += sprintf(p, "%02x", (unsigned)*ptr++);
46 /** @brief Convert a character to its value as a hex digit
47 * @param c Character code
48 * @return Value has hex digit or -1
50 * The 'q' stands for 'quiet' - this function does not report errors.
52 int unhexdigitq(int c) {
64 case 'a': case 'A': return 10;
65 case 'b': case 'B': return 11;
66 case 'c': case 'C': return 12;
67 case 'd': case 'D': return 13;
68 case 'e': case 'E': return 14;
69 case 'f': case 'F': return 15;
74 /** @brief Convert a character to its value as a hex digit
75 * @param c Character code
76 * @return Value has hex digit or -1
78 * If the character is not a valid hex digit then an error is logged.
79 * See @ref unhexdigitq() if that is a problem.
81 int unhexdigit(int c) {
84 if((d = unhexdigitq(c)) < 0) error(0, "invalid hex digit");
88 /** @brief Convert a hex string to bytes
89 * @param s Pointer to hex string
90 * @param np Where to store byte string length or NULL
91 * @return Allocated buffer, or 0
93 * @p s should point to a 0-terminated string containing an even number
94 * of hex digits. They are converted to bytes and returned via the return
95 * value and optionally the length via @p np.
97 * On any error a message is logged and a null pointer is returned.
99 uint8_t *unhex(const char *s, size_t *np) {
104 if((l = strlen(s)) & 1) {
105 error(0, "hex string has odd length");
108 p = buf = xmalloc_noptr(l / 2);
110 if((d1 = unhexdigit(*s++)) < 0) return 0;
111 if((d2 = unhexdigit(*s++)) < 0) return 0;