From: Andreas Steffen Date: Sat, 3 Jun 2023 20:32:19 +0000 (+0200) Subject: utils: Added chunk_to_dec() function X-Git-Tag: 5.9.12rc1~3^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d72d0c0dfaa4ac6a4b4846cbdb0713be235a8ef1;p=thirdparty%2Fstrongswan.git utils: Added chunk_to_dec() function --- diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c index 7328a2caa9..d3e1bd7f65 100644 --- a/src/libstrongswan/tests/suites/test_chunk.c +++ b/src/libstrongswan/tests/suites/test_chunk.c @@ -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"); diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 9150537ce5..f40a379c5f 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -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. */ diff --git a/src/libstrongswan/utils/chunk.h b/src/libstrongswan/utils/chunk.h index f667b9bdff..0ee38d27de 100644 --- a/src/libstrongswan/utils/chunk.h +++ b/src/libstrongswan/utils/chunk.h @@ -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 */