]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
utils: Added chunk_to_dec() function
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 3 Jun 2023 20:32:19 +0000 (22:32 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Nov 2023 11:39:10 +0000 (12:39 +0100)
src/libstrongswan/tests/suites/test_chunk.c
src/libstrongswan/utils/chunk.c
src/libstrongswan/utils/chunk.h

index 7328a2caa9e5e8cf40b777fe6c01a92fe1509f09..d3e1bd7f65c7ba4e150bd02cdbc488eddcda0bf9 100644 (file)
@@ -569,6 +569,57 @@ START_TEST(test_base32)
 }
 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
  */
@@ -1190,6 +1241,7 @@ Suite *chunk_suite_create()
        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");
index 9150537ce5482022e8cd75c092e50920a98c7bd6..f40a379c5f5d112eef8ba305cf768ca48f4efcf5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008-2019 Tobias Brunner
+ * Copyright (C) 2023 Andreas Steffen
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  *
@@ -744,6 +745,71 @@ chunk_t chunk_to_base32(chunk_t chunk, char *buf)
        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.
  */
index f667b9bdffc0fe4d6a84c4fe802f28963387f722..0ee38d27dea830b3204d5af6efcb5d434bc50193 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008-2019 Tobias Brunner
+ * Copyright (C) 2023 Andreas Steffen
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  *
@@ -213,6 +214,18 @@ chunk_t chunk_from_base64(chunk_t base64, char *buf);
  */
 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
  */