예제 #1
0
파일: Base58.cs 프로젝트: ssg/SimpleBase
 /// <summary>
 /// Initializes a new instance of the <see cref="Base58"/> class
 /// using a custom alphabet.
 /// </summary>
 /// <param name="alphabet">Alphabet to use.</param>
 public Base58(Base58Alphabet alphabet)
 {
     this.Alphabet = alphabet;
     this.ZeroChar = alphabet.Value[0];
 }
예제 #2
0
 public Base58(Base58Alphabet alphabet)
 {
     Require.NotNull(alphabet, "alphabet");
     this.alphabet = alphabet;
 }
예제 #3
0
        /// <summary>
        /// Encode to Base58 representation.
        /// </summary>
        /// <param name="bytes">Bytes to encode.</param>
        /// <returns>Encoded string.</returns>
        public unsafe string Encode(ReadOnlySpan <byte> bytes)
        {
            int bytesLen = bytes.Length;

            if (bytesLen == 0)
            {
                return(string.Empty);
            }

            fixed(byte *inputPtr = bytes)
            fixed(char *alphabetPtr = this.Alphabet.Value)
            {
                byte *pInput = inputPtr;
                byte *pEnd   = inputPtr + bytesLen;

                while (pInput != pEnd && *pInput == 0)
                {
                    pInput++;
                }

                int  numZeroes = (int)(pInput - inputPtr);
                char zeroChar  = alphabetPtr[0];

                if (pInput == pEnd)
                {
                    return(new string(zeroChar, numZeroes));
                }

                // we can safely use char count for allocating a byte buffer for the numeric representation
                // because each digit will map to a single character later in the encoding process.
                int outputLen = Base58Alphabet.GetAllocationCharCountForEncoding(bytesLen, numZeroes);
                int length    = 0;

                byte[] output = new byte[outputLen];
                fixed(byte *outputPtr = output)
                {
                    byte *pOutputEnd = outputPtr + outputLen - 1;

                    while (pInput != pEnd)
                    {
                        int carry = *pInput;
                        int i     = 0;
                        for (byte *pDigit = pOutputEnd; (carry != 0 || i < length) &&
                             pDigit >= outputPtr; pDigit--, i++)
                        {
                            carry += 256 * (*pDigit);
                            carry  = Math.DivRem(carry, 58, out int remainder);
                            *pDigit = (byte)remainder;
                        }

                        length = i;
                        pInput++;
                    }

                    pOutputEnd++;
                    byte *pOutput = outputPtr;

                    while (pOutput != pOutputEnd && *pOutput == 0)
                    {
                        pOutput++;
                    }

                    int    resultLen = numZeroes + (int)(pOutputEnd - pOutput);
                    string result    = new string(zeroChar, resultLen);

                    fixed(char *resultPtr = result)
                    {
                        char *pResult = resultPtr + numZeroes;

                        while (pOutput != pOutputEnd)
                        {
                            *pResult++ = alphabetPtr[*pOutput++];
                        }
                    }

                    return(result);
                }
            }
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Base58"/> class
 /// using a custom alphabet.
 /// </summary>
 /// <param name="alphabet">Alphabet to use.</param>
 public Base58(Base58Alphabet alphabet)
 {
     this.Alphabet = alphabet;
 }
예제 #5
0
 public Base58(Base58Alphabet alphabet)
 {
     Require.NotNull(alphabet, nameof(alphabet));
     this.alphabet = alphabet;
 }