Skip to content

Commit

Permalink
[fold] Add explanation of new algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
seelabs committed Nov 16, 2023
1 parent 27e8209 commit 8455956
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/ripple/protocol/impl/tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,95 @@
#include <utility>
#include <vector>

/*
Converting between bases is straight forward. First, some background:
Given the coefficients C[m], ... ,C[0] and base B, those coefficients represent
the number C[m]*B^m + ... + C[0]*B^0; The following pseudo-code converts the
coefficients to the (infinite precision) integer N:
```
N = 0;
i = m ;; N.B. m is the index of the largest coefficient
while (i>=0)
N = N + C[i]*B^i
i = i - 1
```
For example, in base 10, the number 437 represents the integer 4*10^2 + 3*10^1 +
7*10^0. In base 16, 437 is the same as 4*16^2 + 3*16^1 7*16^0.
To find the coefficients that represent the integer N in base B, we start by
computing the lowest order coefficients and work up to the highest order
coefficients. The following pseudo-code converts the (infinite precision)
integer N to the correct coefficients:
```
i = 0
while(N)
C[i] = N mod B
N = floor(N/B)
i = i + 1
```
For example, to find the coefficients of the integer 437 in base 10:
C[0] is 437 mod 10; C[0] = 7;
N is floor(437/10); N = 43;
C[1] is 43 mod 10; C[1] = 3;
N is floor(43/10); N = 4;
C[2] is 4 mod 10; C[2] = 4;
N is floor(4/10); N = 0;
Since N is 0, the algorithm stops.
To convert between a number represented with coefficients from base B1 to that
same number represented with coefficients from base B2, we can use the algorithm
that converts coefficients from base B1 to an integer, and then use the
algorithm that converts a number to coefficients from base B2.
There is a useful shortcut that can be used if one of the bases is a power of
the other base. If B1 == B2^G, then each coefficient from base B1 can be
converted to base B2 independently to create a a group of "G" B2 coefficient.
These coefficients can be simply concatenated together. Since 16 == 2^4, this
property is what makes base 16 useful when dealing with binary numbers. For
example consider converting the base 16 number "93" to binary. The base 16
coefficient 9 is represented in base 2 with the coefficients 1,0,0,1. The base
16 coefficient 3 is represented in base 2 with the coefficients 0,0,1,1. To get
the final answer, just concatenate those two independent conversions together.
The base 16 number "93" is the binary number "10010011".
The original algorithm to convert from base 58 to a number to a binary number
used the
```
N = 0;
for i in m to 0 inclusive
N = N + C[i]*B^i
```
algorithm.
However, the algorithm above is pseudo-code. In particular, the variable "N" is
an infinite precision integer in that pseudo-code. Real computers do
computations on registers, and these registers have limited length. Modern
computers use 64-bit general purpose registers, and can multiply two 64 bit
numbers and obtain a 128 bit result (in two registers).
The original algorithm in essence converted from base 58 to base 256 (base
2^8). The new, faster algorithm converts from base 58 to base 58^10 (this is
fast using the shortcut described above), then from base 58^10 to base 2^64
(this is slow, and requires multi-precision arithmetic), and then from base 2^64
to base 2^8 (this is fast, using the shortcut described above).
While it may seem counter-intuitive that converting from base 58 -> base 58^10
-> base 2^64 -> base 2^8 is faster than directly converting from base 58 -> base
2^8, it is actually 10x-15x faster. The reason for the speed increase is two of
the conversions are trivial (converting between bases where one base is a power
of another base), and doing the multi-precision computations with larger
coefficients sizes greatly speeds up the multi-precision computations.
*/

namespace ripple {

static constexpr char const* alphabetForward =
Expand Down

0 comments on commit 8455956

Please sign in to comment.