From 8cad0d8e9a1c1437102c58ed761973b36617cbc3 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 17 May 2018 17:53:11 +0900 Subject: [PATCH] add hexToArray --- src/conversion.hpp | 36 +++++++++++++++++++++++++++++++----- src/fp.cpp | 20 +++++++++++++++++--- test/conversion_test.cpp | 4 ++-- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/conversion.hpp b/src/conversion.hpp index 9292a72..039af4a 100644 --- a/src/conversion.hpp +++ b/src/conversion.hpp @@ -111,6 +111,32 @@ void fromStr16(T *x, size_t xn, const char *str, size_t strLen) for (size_t i = requireSize; i < xn; i++) x[i] = 0; } +/* + convert hex string to x[0..xn) + hex string = [0-9a-fA-F]+ +*/ +template +inline size_t hexToArray(UT *x, size_t maxN, const char *buf, size_t bufSize) +{ + if (bufSize == 0) return 0; + const size_t unitLen = sizeof(UT) * 2; + const size_t q = bufSize / unitLen; + const size_t r = bufSize % unitLen; + const size_t requireSize = q + (r ? 1 : 0); + if (maxN < requireSize) return 0; + for (size_t i = 0; i < q; i++) { + bool b; + x[i] = cybozu::hextoi(&b, &buf[r + (q - 1 - i) * unitLen], unitLen); + if (!b) return 0; + } + if (r) { + bool b; + x[q] = cybozu::hextoi(&b, buf, r); + if (!b) return 0; + } + return requireSize; +} + namespace local { /* @@ -225,14 +251,14 @@ inline size_t arrayToDec(char *buf, size_t bufSize, const UT *x, size_t xn) return written num if success else 0 */ template -inline size_t convertDecToArray(UT *_x, size_t xSize, const char *buf, size_t bufSize) +inline size_t decToArray(UT *_x, size_t maxN, const char *buf, size_t bufSize) { assert(sizeof(UT) == 4 || sizeof(UT) == 8); const size_t width = 9; const uint32_t i1e9 = 1000000000U; - if (xSize == 0) return 0; + if (maxN == 0) return 0; if (sizeof(UT) == 8) { - xSize *= 2; + maxN *= 2; } uint32_t *x = reinterpret_cast(_x); size_t xn = 1; @@ -245,12 +271,12 @@ inline size_t convertDecToArray(UT *_x, size_t xSize, const char *buf, size_t bu if (!b) return 0; uint32_t H = local::mulU32(x, x, xn, i1e9); if (H > 0) { - if (xn == xSize) return 0; + if (xn == maxN) return 0; x[xn++] = H; } H = local::addU32(x, xn, v); if (H > 0) { - if (xn == xSize) return 0; + if (xn == maxN) return 0; x[xn++] = H; } buf += n; diff --git a/src/fp.cpp b/src/fp.cpp index bcbb23f..b015226 100644 --- a/src/fp.cpp +++ b/src/fp.cpp @@ -647,14 +647,28 @@ bool strToArray(bool *pIsMinus, Unit *x, size_t xN, const char *buf, size_t bufS ioMode &= 0xff; size_t readSize; if (!parsePrefix(&readSize, pIsMinus, &ioMode, buf, bufSize)) return false; -#if 0 -#else +#if 1 + if (ioMode == 10) { + size_t n = mcl::fp::decToArray(x, xN, buf + readSize, bufSize - readSize); + if (n == 0) return false; + for (size_t i = n; i < xN; i++) { + x[i] = 0; + } + return true; + } else if (ioMode == 16) { + size_t n = mcl::fp::hexToArray(x, xN, buf + readSize, bufSize - readSize); + if (n == 0) return false; + for (size_t i = n; i < xN; i++) { + x[i] = 0; + } + return true; + } +#endif mpz_class mx; if (!gmp::setStr(mx, std::string(buf + readSize, bufSize - readSize), ioMode)) { return false; } gmp::getArray(x, xN, mx); -#endif return true; } diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp index 3f1f959..41b4203 100644 --- a/test/conversion_test.cpp +++ b/test/conversion_test.cpp @@ -33,7 +33,7 @@ CYBOZU_TEST_AUTO(arrayToDec) CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n); const size_t maxN = 32; uint32_t xx[maxN] = {}; - size_t xn = mcl::fp::convertDecToArray(xx, maxN, str, strLen); + size_t xn = mcl::fp::decToArray(xx, maxN, str, strLen); CYBOZU_TEST_EQUAL(xn, tbl[i].xn); CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn); } @@ -50,7 +50,7 @@ CYBOZU_TEST_AUTO(arrayToDec) CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n); const size_t maxN = 32; uint64_t xx[maxN] = {}; - size_t xxn = mcl::fp::convertDecToArray(xx, maxN, str, strLen); + size_t xxn = mcl::fp::decToArray(xx, maxN, str, strLen); CYBOZU_TEST_EQUAL(xxn, xn); CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn); }