diff --git a/src/crypto/base36.cpp b/src/crypto/base36.cpp index 5a2f157..2264341 100644 --- a/src/crypto/base36.cpp +++ b/src/crypto/base36.cpp @@ -7,9 +7,20 @@ namespace fc fc::string to_base36( const char* data, size_t len ) { if( len == 0 ) return fc::string(); - fc::bigint value( data, len ); + + const char* src = data; + int src_len = len; + char buffer[len+1]; + if (*data & 0x80) { + buffer[0] = 0; + memcpy( buffer + 1, data, len ); + src = buffer; + src_len++; + } + fc::bigint value( src, src_len ); + auto base36 = "0123456789abcdefghijklmnopqrstuvwxyz"; - std::vector out( static_cast(len * 1.6) + 1 ); + std::vector out( static_cast(len * 1.6) + 2 ); int pos = out.size() - 1; out[pos] = '\0'; fc::bigint _36(36); @@ -19,7 +30,7 @@ namespace fc out[pos] = base36[(value % _36).to_int64()]; } } while (value /= _36); - while (*data++ == 0) { + while (len-- > 0 && *data++ == 0) { out[--pos] = '0'; } return &out[pos]; //fc::string( &out[pos], out.size() - pos); @@ -61,7 +72,7 @@ namespace fc const char *in = b36.c_str(); while (*in++ == '0') { leading_zeros++; } char* first = bytes.data(); - while (*first == 0) { first++; len--; } + while (len > 0 && *first == 0) { first++; len--; } std::vector result; result.resize(leading_zeros + len, 0); memcpy( result.data() + leading_zeros, first, len ); diff --git a/tests/crypto/base_n_tests.cpp b/tests/crypto/base_n_tests.cpp index b3e65ac..a501123 100644 --- a/tests/crypto/base_n_tests.cpp +++ b/tests/crypto/base_n_tests.cpp @@ -12,6 +12,8 @@ static const std::string TEST1(""); static const std::string TEST2("\0\00101", 4); static const std::string TEST3("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); +static const std::string TEST4("\377\376\000\375\001\374", 6); +static const std::string TEST5("\0\0\0", 3); static void test_16( const std::string& test, const std::string& expected ) { @@ -37,6 +39,8 @@ BOOST_AUTO_TEST_CASE(hex_test) test_16( TEST1, "" ); test_16( TEST2, "00013031" ); test_16( TEST3, "4142434445464748494a4b4c4d4e4f505152535455565758595a" ); + test_16( TEST4, "fffe00fd01fc" ); + test_16( TEST5, "000000" ); } @@ -58,6 +62,8 @@ BOOST_AUTO_TEST_CASE(base32_test) test_32( TEST1, "" ); test_32( TEST2, "AAATAMI=" ); test_32( TEST3, "IFBEGRCFIZDUQSKKJNGE2TSPKBIVEU2UKVLFOWCZLI======" ); + test_32( TEST4, "777AB7IB7Q======" ); + test_32( TEST5, "AAAAA===" ); } @@ -79,6 +85,8 @@ BOOST_AUTO_TEST_CASE(base36_test) test_36( TEST1, "" ); test_36( TEST2, "01o35" ); test_36( TEST3, "l4ksdleyi5pnl0un5raue268ptj43dwjwmz15ie2" ); + test_36( TEST4, "2rrrvpb7y4" ); + test_36( TEST5, "000" ); } @@ -112,6 +120,8 @@ BOOST_AUTO_TEST_CASE(base58_test) test_58( TEST1, "" ); test_58( TEST2, "1Q9e" ); test_58( TEST3, "2zuFXTJSTRK6ESktqhM2QDBkCnH1U46CnxaD" ); + test_58( TEST4, "3CUeREErf" ); + test_58( TEST5, "111" ); } @@ -132,6 +142,8 @@ BOOST_AUTO_TEST_CASE(base64_test) test_64( TEST1, "" ); test_64( TEST2, "AAEwMQ==" ); test_64( TEST3, "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=" ); + test_64( TEST4, "//4A/QH8" ); + test_64( TEST5, "AAAA" ); }