mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:37:35 +00:00
LibCrypto: Define *BigInteger::to_base to convert big integers to String
This commit is contained in:
parent
0ddc2e1f50
commit
3ad1f250e7
5 changed files with 28 additions and 12 deletions
|
@ -241,9 +241,10 @@ TEST_CASE(test_unsigned_bigint_base10_from_string)
|
||||||
|
|
||||||
TEST_CASE(test_unsigned_bigint_base10_to_string)
|
TEST_CASE(test_unsigned_bigint_base10_to_string)
|
||||||
{
|
{
|
||||||
auto result = Crypto::UnsignedBigInteger {
|
auto bigint = Crypto::UnsignedBigInteger {
|
||||||
Vector<u32> { 3806301393, 954919431, 3879607298, 721 }
|
Vector<u32> { 3806301393, 954919431, 3879607298, 721 }
|
||||||
}.to_base_deprecated(10);
|
};
|
||||||
|
auto result = MUST(bigint.to_base(10));
|
||||||
EXPECT_EQ(result, "57195071295721390579057195715793");
|
EXPECT_EQ(result, "57195071295721390579057195715793");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,10 +387,10 @@ TEST_CASE(test_bigint_random_distribution)
|
||||||
"100000000000000000000000000000"_bigint); // 10**29
|
"100000000000000000000000000000"_bigint); // 10**29
|
||||||
if (actual_result < "100000000000000000000"_bigint) { // 10**20
|
if (actual_result < "100000000000000000000"_bigint) { // 10**20
|
||||||
FAIL("Too small");
|
FAIL("Too small");
|
||||||
outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base_deprecated(10));
|
outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", MUST(actual_result.to_base(10)));
|
||||||
} else if ("99999999900000000000000000000"_bigint < actual_result) { // 10**29 - 10**20
|
} else if ("99999999900000000000000000000"_bigint < actual_result) { // 10**29 - 10**20
|
||||||
FAIL("Too large");
|
FAIL("Too large");
|
||||||
outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base_deprecated(10));
|
outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", MUST(actual_result.to_base(10)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,16 +51,22 @@ SignedBigInteger SignedBigInteger::from_base(u16 N, StringView str)
|
||||||
return { move(unsigned_data), sign };
|
return { move(unsigned_data), sign };
|
||||||
}
|
}
|
||||||
|
|
||||||
DeprecatedString SignedBigInteger::to_base_deprecated(u16 N) const
|
ErrorOr<String> SignedBigInteger::to_base(u16 N) const
|
||||||
{
|
{
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
|
|
||||||
if (m_sign)
|
if (m_sign)
|
||||||
builder.append('-');
|
TRY(builder.try_append('-'));
|
||||||
|
|
||||||
builder.append(m_unsigned_data.to_base_deprecated(N));
|
auto unsigned_as_base = TRY(m_unsigned_data.to_base(N));
|
||||||
|
TRY(builder.try_append(unsigned_as_base.bytes_as_string_view()));
|
||||||
|
|
||||||
return builder.to_deprecated_string();
|
return builder.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeprecatedString SignedBigInteger::to_base_deprecated(u16 N) const
|
||||||
|
{
|
||||||
|
return MUST(to_base(N)).to_deprecated_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 SignedBigInteger::to_u64() const
|
u64 SignedBigInteger::to_u64() const
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <AK/Concepts.h>
|
#include <AK/Concepts.h>
|
||||||
#include <AK/Span.h>
|
#include <AK/Span.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||||
|
|
||||||
namespace Crypto {
|
namespace Crypto {
|
||||||
|
@ -63,6 +64,7 @@ public:
|
||||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||||
|
|
||||||
[[nodiscard]] static SignedBigInteger from_base(u16 N, StringView str);
|
[[nodiscard]] static SignedBigInteger from_base(u16 N, StringView str);
|
||||||
|
[[nodiscard]] ErrorOr<String> to_base(u16 N) const;
|
||||||
[[nodiscard]] DeprecatedString to_base_deprecated(u16 N) const;
|
[[nodiscard]] DeprecatedString to_base_deprecated(u16 N) const;
|
||||||
|
|
||||||
[[nodiscard]] u64 to_u64() const;
|
[[nodiscard]] u64 to_u64() const;
|
||||||
|
|
|
@ -146,11 +146,11 @@ UnsignedBigInteger UnsignedBigInteger::from_base(u16 N, StringView str)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeprecatedString UnsignedBigInteger::to_base_deprecated(u16 N) const
|
ErrorOr<String> UnsignedBigInteger::to_base(u16 N) const
|
||||||
{
|
{
|
||||||
VERIFY(N <= 36);
|
VERIFY(N <= 36);
|
||||||
if (*this == UnsignedBigInteger { 0 })
|
if (*this == UnsignedBigInteger { 0 })
|
||||||
return "0";
|
return String::from_utf8("0"sv);
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
UnsignedBigInteger temp(*this);
|
UnsignedBigInteger temp(*this);
|
||||||
|
@ -160,11 +160,16 @@ DeprecatedString UnsignedBigInteger::to_base_deprecated(u16 N) const
|
||||||
while (temp != UnsignedBigInteger { 0 }) {
|
while (temp != UnsignedBigInteger { 0 }) {
|
||||||
UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(temp, N, quotient, remainder);
|
UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(temp, N, quotient, remainder);
|
||||||
VERIFY(remainder.words()[0] < N);
|
VERIFY(remainder.words()[0] < N);
|
||||||
builder.append(to_ascii_base36_digit(remainder.words()[0]));
|
TRY(builder.try_append(to_ascii_base36_digit(remainder.words()[0])));
|
||||||
temp.set_to(quotient);
|
temp.set_to(quotient);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.to_deprecated_string().reverse();
|
return TRY(builder.to_string()).reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeprecatedString UnsignedBigInteger::to_base_deprecated(u16 N) const
|
||||||
|
{
|
||||||
|
return MUST(to_base(N)).to_deprecated_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 UnsignedBigInteger::to_u64() const
|
u64 UnsignedBigInteger::to_u64() const
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <AK/Concepts.h>
|
#include <AK/Concepts.h>
|
||||||
#include <AK/DeprecatedString.h>
|
#include <AK/DeprecatedString.h>
|
||||||
#include <AK/Span.h>
|
#include <AK/Span.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ public:
|
||||||
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
size_t export_data(Bytes, bool remove_leading_zeros = false) const;
|
||||||
|
|
||||||
[[nodiscard]] static UnsignedBigInteger from_base(u16 N, StringView str);
|
[[nodiscard]] static UnsignedBigInteger from_base(u16 N, StringView str);
|
||||||
|
[[nodiscard]] ErrorOr<String> to_base(u16 N) const;
|
||||||
[[nodiscard]] DeprecatedString to_base_deprecated(u16 N) const;
|
[[nodiscard]] DeprecatedString to_base_deprecated(u16 N) const;
|
||||||
|
|
||||||
[[nodiscard]] u64 to_u64() const;
|
[[nodiscard]] u64 to_u64() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue