}
END_TEST
+/*******************************************************************************
+ * DEC encoding test
+ */
+
+START_TEST(test_dec)
+{
+ typedef struct {
+ chunk_t in;
+ char *out;
+ } testdata_t;
+
+ testdata_t test[] = {
+ { chunk_from_chars( 0x00), "0" },
+ { chunk_from_chars( 0x09), "9" },
+ { chunk_from_chars( 0x0a), "10" },
+ { chunk_from_chars( 0x13), "19" },
+ { chunk_from_chars( 0x14), "20" },
+ { chunk_from_chars( 0x63), "99" },
+ { chunk_from_chars( 0x64), "100" },
+ { chunk_from_chars( 0x65), "101" },
+ { chunk_from_chars( 0xff), "255" },
+ { chunk_from_chars( 0x00, 0xff), "255" },
+ { chunk_from_chars( 0x01, 0x00), "256" },
+ { chunk_from_chars( 0x01, 0x03), "259" },
+ { chunk_from_chars( 0x01, 0x04), "260" },
+ { chunk_from_chars( 0x09, 0xff), "2559" },
+ { chunk_from_chars( 0x0a, 0x00), "2560" },
+ { chunk_from_chars( 0x0a, 0x01), "2561" },
+ { chunk_from_chars( 0xff, 0xff), "65535" },
+ { chunk_from_chars(0x00, 0xff, 0xff), "65535" },
+ { chunk_from_chars(0x01, 0x00, 0x00), "65536" },
+ { chunk_from_chars(0x01, 0x86, 0x9f), "99999" },
+ { chunk_from_chars(0x01, 0x86, 0xa0), "100000" },
+ { chunk_from_chars(0x0f, 0x42, 0x40), "1000000" },
+ { chunk_from_chars(0xa9, 0x8a, 0xc7), "11111111" },
+ { chunk_from_chars(0xbc, 0x61, 0x4e), "12345678" },
+ };
+
+ int i;
+
+ for (i = 0; i < countof(test); i++)
+ {
+ char buf[10];
+ chunk_t out;
+
+ out = chunk_to_dec(test[i].in, buf);
+ ck_assert_str_eq(out.ptr, test[i].out);
+ }
+}
+END_TEST
+
/*******************************************************************************
* chunk_increment test
*/
tcase_add_test(tc, test_base64);
tcase_add_test(tc, test_base32);
tcase_add_test(tc, test_base16);
+ tcase_add_test(tc, test_dec);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_mac");
/*
* Copyright (C) 2008-2019 Tobias Brunner
+ * Copyright (C) 2023 Andreas Steffen
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
*
return chunk_create(buf, len * 8 / 5);
}
+/**
+ * Described in header.
+ */
+chunk_t chunk_to_dec(chunk_t chunk, char *buf)
+{
+ int len, i, i_buf, i_bin = 0;
+ uint16_t remainder;
+ chunk_t bin;
+
+ /* Determine the number of needed decimal digits:
+ * 10^len > 2^(8*chunk.len) =>
+ * len > log(256) * chunk.len =>
+ * len > 2.4083 * chunk.len
+ */
+ len = (int)(2.4083 * (double)chunk.len) + 1;
+
+ if (!buf)
+ {
+ buf = malloc(len + 1);
+ }
+ i_buf = len;
+ buf[i_buf] = '\0';
+ bin = chunk_clone(chunk);
+ while (i_bin < bin.len)
+ {
+ remainder = 0;
+ for (i = i_bin; i < bin.len; i++)
+ {
+ remainder = bin.ptr[i] + (remainder << 8);
+ if (remainder < 10)
+ {
+ remainder = bin.ptr[i];
+ bin.ptr[i] = 0;
+ if (i == i_bin)
+ {
+ i_bin++;
+ }
+ }
+ else
+ {
+ bin.ptr[i] = remainder / 10;
+ remainder %= 10;
+ }
+ }
+ if (i_buf > 0)
+ {
+ buf[--i_buf] = 0x30 + remainder;
+ }
+ }
+ chunk_free(&bin);
+
+ /* align decimal number to the start of the string */
+ if (i_buf > 0)
+ {
+ len -= i_buf;
+
+ for (i = 0; i <= len; i++)
+ {
+ buf[i] = buf[i + i_buf];
+ }
+ }
+
+ return chunk_create(buf, len);
+}
+
/**
* Described in header.
*/
/*
* Copyright (C) 2008-2019 Tobias Brunner
+ * Copyright (C) 2023 Andreas Steffen
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
*
*/
chunk_t chunk_to_base32(chunk_t chunk, char *buf);
+/**
+ * Convert a chunk of data to decimal encoding.
+ *
+ * The resulting string is '\\0' terminated, but the chunk does not include
+ * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2.41 + 1).
+ *
+ * @param chunk data to convert to decimal encoding
+ * @param buf buffer to write to, NULL to malloc
+ * @return chunk of encoded data
+ */
+chunk_t chunk_to_dec(chunk_t chunk, char *buf);
+
/**
* Free contents of a chunk
*/