--- /dev/null
+../../../licenses/CC0
\ No newline at end of file
--- /dev/null
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * str/hex - hex-to-string conversions and vice-versa
+ *
+ * This code contains simple routines for hexidecimal strings.
+ *
+ * License: CC0 (Public domain)
+ * Author: Rusty Russell <rusty@rustcorp.com.au>
+ *
+ * Example:
+ * int main(int argc, char *argv[])
+ * {
+ * int i;
+ *
+ * for (i = 1; i < argc; i++) {
+ * char str[hex_str_size(strlen(argv[i]))];
+ *
+ * hex_encode(str, sizeof(str), argv[i], strlen(argv[i]));
+ * printf("%s ", str);
+ * }
+ * printf("\n");
+ * return 0;
+ * }
+ */
+int main(int argc, char *argv[])
+{
+ /* Expect exactly one argument */
+ if (argc != 2)
+ return 1;
+
+ if (strcmp(argv[1], "depends") == 0) {
+ return 0;
+ }
+
+ return 1;
+}
--- /dev/null
+/* CC0 license (public domain) - see LICENSE file for details */
+#include <ccan/str/hex/hex.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static bool char_to_hex(unsigned char *val, char c)
+{
+ if (c >= '0' && c <= '9') {
+ *val = c - '0';
+ return true;
+ }
+ if (c >= 'a' && c <= 'f') {
+ *val = c - 'a' + 10;
+ return true;
+ }
+ if (c >= 'A' && c <= 'F') {
+ *val = c - 'A' + 10;
+ return true;
+ }
+ return false;
+}
+
+bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize)
+{
+ unsigned char v1, v2;
+ unsigned char *p = buf;
+
+ while (slen > 1) {
+ if (!char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1]))
+ return false;
+ if (!bufsize)
+ return false;
+ *(p++) = (v1 << 4) | v2;
+ str += 2;
+ slen -= 2;
+ bufsize--;
+ }
+ return slen == 0 && bufsize == 0;
+}
+
+static char hexchar(unsigned int val)
+{
+ if (val < 10)
+ return '0' + val;
+ if (val < 16)
+ return 'a' + val - 10;
+ abort();
+}
+
+bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize)
+{
+ size_t used = 0;
+
+ if (destsize < 1)
+ return false;
+
+ while (used < bufsize) {
+ unsigned int c = ((const unsigned char *)buf)[used];
+ if (destsize < 3)
+ return false;
+ *(dest++) = hexchar(c >> 4);
+ *(dest++) = hexchar(c & 0xF);
+ used++;
+ destsize -= 2;
+ }
+ *dest = '\0';
+
+ return used + 1;
+}
--- /dev/null
+/* CC0 (Public domain) - see LICENSE file for details */
+#ifndef CCAN_HEX_H
+#define CCAN_HEX_H
+#include "config.h"
+#include <stdbool.h>
+#include <stdlib.h>
+
+/**
+ * hex_decode - Unpack a hex string.
+ * @str: the hexidecimal string
+ * @slen: the length of @str
+ * @buf: the buffer to write the data into
+ * @bufsize: the length of @buf
+ *
+ * Returns false if there are any characters which aren't 0-9, a-f or A-F,
+ * of the string wasn't the right length for @bufsize.
+ *
+ * Example:
+ * unsigned char data[20];
+ *
+ * if (!hex_decode(argv[1], strlen(argv[1]), data, 20))
+ * printf("String is malformed!\n");
+ */
+bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize);
+
+/**
+ * hex_encode - Create a nul-terminated hex string
+ * @buf: the buffer to read the data from
+ * @bufsize: the length of @buf
+ * @dest: the string to fill
+ * @destsize: the max size of the string
+ *
+ * Returns true if the string, including terminator, fit in @destsize;
+ *
+ * Example:
+ * unsigned char buf[] = { 0x1F, 0x2F };
+ * char str[5];
+ *
+ * if (!hex_encode(buf, sizeof(buf), str, sizeof(str)))
+ * abort();
+ */
+bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize);
+
+/**
+ * hex_str_size - Calculate how big a nul-terminated hex string is
+ * @bytes: bytes of data to represent
+ *
+ * Example:
+ * unsigned char buf[] = { 0x1F, 0x2F };
+ * char str[hex_str_size(sizeof(buf))];
+ *
+ * hex_encode(buf, sizeof(buf), str, sizeof(str));
+ */
+static inline size_t hex_str_size(size_t bytes)
+{
+ return 2 * bytes + 1;
+}
+
+/**
+ * hex_data_size - Calculate how many bytes of data in a hex string
+ * @strlen: the length of the string (with or without NUL)
+ *
+ * Example:
+ * const char str[] = "1F2F";
+ * unsigned char buf[hex_data_size(sizeof(str))];
+ *
+ * hex_decode(str, strlen(str), buf, sizeof(buf));
+ */
+static inline size_t hex_data_size(size_t strlen)
+{
+ return strlen / 2;
+}
+#endif /* PETTYCOIN_HEX_H */
--- /dev/null
+#include <ccan/str/hex/hex.h>
+/* Include the C files directly. */
+#include <ccan/str/hex/hex.c>
+#include <ccan/tap/tap.h>
+#include <string.h>
+
+int main(void)
+{
+ const char teststr[] = "0123456789abcdefABCDEF";
+ const char bad_teststr[] = "0123456789abcdefABCDEF1O";
+ const unsigned char testdata[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+ 0xcd, 0xef, 0xAB, 0xCD, 0xEF };
+ unsigned char data[11];
+ char str[23];
+ size_t i;
+
+ plan_tests(10 + sizeof(str));
+
+ ok1(hex_str_size(sizeof(testdata)) == sizeof(teststr));
+ /* This gives right result with or without nul included */
+ ok1(hex_data_size(strlen(teststr)) == sizeof(testdata));
+ ok1(hex_data_size(sizeof(teststr)) == sizeof(testdata));
+
+ ok1(hex_decode(teststr, strlen(teststr), data, sizeof(data)));
+ ok1(memcmp(data, testdata, sizeof(testdata)) == 0);
+ ok1(hex_encode(testdata, sizeof(testdata), str, sizeof(str)));
+ ok1(strcmp(str, "0123456789abcdefabcdef") == 0);
+
+ /* Bad char */
+ ok1(!hex_decode(bad_teststr, strlen(bad_teststr), data, sizeof(data)));
+ /* Bad hex string len */
+ ok1(!hex_decode(teststr, strlen(teststr) - 1, data, sizeof(data)));
+ /* Bad buffer len */
+ ok1(!hex_decode(teststr, strlen(teststr), data, sizeof(data) - 1));
+
+ /* Bad deststring size. */
+ for (i = 1; i <= sizeof(str); i++)
+ ok1(!hex_encode(testdata, sizeof(testdata), str, sizeof(str)-i));
+
+ /* This exits depending on whether all tests passed */
+ return exit_status();
+}