Base58Check encoding: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Perl 6}}: Added Perl 6 solution)
(added haskell)
Line 8: Line 8:


The ''reference algorithm'' is at [https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart the Bitcoin's Base58Check page].
The ''reference algorithm'' is at [https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart the Bitcoin's Base58Check page].

=={{header|Haskell}}==
<lang haskell>import Numeric (showIntAtBase)

chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

base58Encode :: Integer -> String
base58Encode n = showIntAtBase 58 (chars !!) n ""

main :: IO ()
main = mapM_ (putStrLn . base58Encode)
[25420294593250030202636073700053352635053786165627414518,
0x61,
0x626262,
0x636363,
0x73696d706c792061206c6f6e6720737472696e67,
0x516b6fcd0f,
0xbf4f89001e670274dd,
0x572e4794,
0xecac89cad93923c02321,
0x10c8511e]</lang>
{{out}}
<pre>
6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
2g
a3gV
aPEr
2cFupjhnEsSn59qHXstmK2ffpLv2
ABnLTmg
3SEo3LWLoPntC
3EFU7m
EJDM8drfXA6uyA
Rt5zm
</pre>


=={{header|Perl 6}}==
=={{header|Perl 6}}==

Revision as of 07:07, 13 August 2017


The popular encoding of small and medium-sized checksums is base16, that is more compact than usual base10 and is human readable... For checksums resulting in hash digests bigger than ~100 bits, the base16 is too long: base58 is shorter and (when using good alphabet) preserves secure human readability. The most popular alphabet of base58 is the variant used in bitcoin address (see Bitcoin/address validation), so it is the "default base58 alphabet".

Write a program that takes a checksum (resultant hash digest) integer binary representation as argument, and converts (encode it) into base58 with the standard Bitcoin alphabet — which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters 0, O, I and l.

The reference algorithm is at the Bitcoin's Base58Check page.

Haskell

<lang haskell>import Numeric (showIntAtBase)

chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

base58Encode :: Integer -> String base58Encode n = showIntAtBase 58 (chars !!) n ""

main :: IO () main = mapM_ (putStrLn . base58Encode)

       [25420294593250030202636073700053352635053786165627414518,
        0x61,
        0x626262,
        0x636363,
        0x73696d706c792061206c6f6e6720737472696e67,
        0x516b6fcd0f,
        0xbf4f89001e670274dd,
        0x572e4794,
        0xecac89cad93923c02321,
        0x10c8511e]</lang>
Output:
6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
2g
a3gV
aPEr
2cFupjhnEsSn59qHXstmK2ffpLv2
ABnLTmg
3SEo3LWLoPntC
3EFU7m
EJDM8drfXA6uyA
Rt5zm

Perl 6

<lang perl6>sub encode_Base58 ( Int $x ) {

   constant @codes = <
         1 2 3 4 5 6 7 8 9
       A B C D E F G H   J K L M N   P Q R S T U V W X Y Z
       a b c d e f g h i j k   m n o p q r s t u v w x y z
   >;
   return @codes[ $x.polymod( 58 xx * ) ].join.flip;

}

my @tests =

   25420294593250030202636073700053352635053786165627414518 => '6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM',
   0x61                    => '2g',
   0x626262                => 'a3gV',
   0x636363                => 'aPEr',
   0x73696d706c792061206c6f6e6720737472696e67 => '2cFupjhnEsSn59qHXstmK2ffpLv2',
   0x516b6fcd0f            => 'ABnLTmg',
   0xbf4f89001e670274dd    => '3SEo3LWLoPntC',
   0x572e4794              => '3EFU7m',
   0xecac89cad93923c02321  => 'EJDM8drfXA6uyA',
   0x10c8511e              => 'Rt5zm',

use Test; for @tests {

   is encode_Base58(.key), .value, "{.key} encodes to {.value}";

} </lang>