Base58Check encoding: Difference between revisions

→‎{{header|RPL}}: improved processing of large binary integers
(Added Quackery.)
(→‎{{header|RPL}}: improved processing of large binary integers)
 
(16 intermediate revisions by 10 users not shown)
Line 1:
{{draft task}}
[[Category:Encodings]]
[[Category:Checksums]]
{{draft task}}
 
The popular encoding of small and medium-sized [[:Category:Checksums|checksums]] is [[wp:base16|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: [[wp:base58|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".
Line 14:
The ''reference algorithm'' is at [https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart the Bitcoin's Base58Check page].
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V ALPHABET = ‘123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz’
 
F convertToBase58(=num)
V sb = ‘’
L num > 0
V r = Int(num % 58)
sb = sb‘’:ALPHABET[r]
num = num I/ 58
R reversed(sb)
 
V s = BigInt(‘25420294593250030202636073700053352635053786165627414518’)
V b = convertToBase58(s)
print(‘#. -> #.’.format(s, b))
 
V hash_arr = [‘61’, ‘626262’, ‘636363’, ‘73696d706c792061206c6f6e6720737472696e67’, ‘516b6fcd0f’, ‘bf4f89001e670274dd’, ‘572e4794’, ‘ecac89cad93923c02321’, ‘10c8511e’]
L(num) hash_arr
b = convertToBase58(BigInt(num, radix' 16))
print(‘0x#<54 -> #.’.format(num, b))</syntaxhighlight>
 
{{out}}
<pre>
25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
0x61 -> 2g
0x626262 -> a3gV
0x636363 -> aPEr
0x73696d706c792061206c6f6e6720737472696e67 -> 2cFupjhnEsSn59qHXstmK2ffpLv2
0x516b6fcd0f -> ABnLTmg
0xbf4f89001e670274dd -> 3SEo3LWLoPntC
0x572e4794 -> 3EFU7m
0xecac89cad93923c02321 -> EJDM8drfXA6uyA
0x10c8511e -> Rt5zm
</pre>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Numerics;
Line 87 ⟶ 123:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 101 ⟶ 137:
 
=={{header|D}}==
<langsyntaxhighlight Dlang="d">import std.bigint;
import std.stdio;
 
Line 149 ⟶ 185:
return sb.data.idup;
}
}</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 164 ⟶ 200:
=={{header|FreeBASIC}}==
{{libheader|GMP}}
<langsyntaxhighlight lang="freebasic">' version 14-08-2017
' compile with: fbc -s console
' uses GMP
Line 223 ⟶ 259:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>OkobppXBkab(58) --> RosettaCode
Line 240 ⟶ 276:
=={{header|Go}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 302 ⟶ 338:
fmt.Printf("%-56s -> %s\n", hash, b58)
}
}</langsyntaxhighlight>
 
{{out}}
Line 320 ⟶ 356:
=={{header|Groovy}}==
{{trans|Java}}
<langsyntaxhighlight lang="groovy">class Base58CheckEncoding {
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
private static final BigInteger BIG0 = BigInteger.ZERO
Line 368 ⟶ 404:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 382 ⟶ 418:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import Numeric (showIntAtBase)
 
chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
Line 400 ⟶ 436:
0x572e4794,
0xecac89cad93923c02321,
0x10c8511e]</langsyntaxhighlight>
{{out}}
<pre>
Line 417 ⟶ 453:
and for bulk encoding, Array access would be one of various slightly faster alternatives to recursive subscripting of linked lists:
{{Trans|Python}}
<langsyntaxhighlight Haskelllang="haskell">import Data.Array (Array, listArray, (!), listArray)
import Numeric (showHex, showIntAtBase)
 
------------------- BASE58CHECK ENCODING -----------------
base58Encode
 
:: (Integral a, Show a)
base58Encode ::
=> a -> String
(Integral a, Show a) =>
a ->
String
base58Encode =
baseEncode $
listArray (0, 57) $
[('1', '9'), ('A', 'H'), ('J', 'N'),[ ('P1', 'Z9'), ('a', 'k'), ('m', 'z')] >>=
('A', 'H'),
uncurry enumFromTo
('J', 'N'),
('P', 'Z'),
('a', 'k'),
('m', 'z')
]
>>= uncurry enumFromTo
 
baseEncode ::
:: (Show a, Integral a) =>
=> Array Int Char -> a -> String
a ->
baseEncode cs n = showIntAtBase (fromIntegral $ length cs) (cs !) n []
String
baseEncode cs n =
showIntAtBase
(fromIntegral $ length cs)
(cs !)
n
[]
 
-- TEST -------------------------- TEST -------------------------
main :: IO ()
main =
putStrLn $
fTable
"Base 58 encoding:\n"
((\x"0x" -<>) '0'. : 'x' :flip showHex x [])
base58Encode
id
[ 25420294593250030202636073700053352635053786165627414518,
, 0x61,
, 0x626262,
, 0x636363,
, 0x73696d706c792061206c6f6e6720737472696e67,
, 0x516b6fcd0f,
, 0xbf4f89001e670274dd,
, 0x572e4794,
, 0xecac89cad93923c02321,
, 0x10c8511e
]
 
-- OUTPUT FORMATTING ------------------- OUTPUT FORMATTING -------------------
fTable ::
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
let w = maximum $ fmap length (xShow <$> xs)
rjust n c s = (drop (. length s) <*> (replicate n c ++ s<>)
in unlines $
s :
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs</lang>
fmap
( ((<>) . rjust w ' ' . xShow)
<*> ((" -> " <>) . fxShow . f)
)
xs</syntaxhighlight>
{{Out}}
<pre>Base 58 encoding:
Line 479 ⟶ 542:
{{trans|Kotlin}}
{{works with|Java|9}}
<langsyntaxhighlight Javalang="java">import java.math.BigInteger;
import java.util.List;
 
Line 530 ⟶ 593:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 542 ⟶ 605:
0xecac89cad93923c02321 -> EJDM8drfXA6uyA
0x10c8511e -> Rt5zm</pre>
 
=={{header|jq}}==
'''Works with gojq, the Go implementation of jq'''
 
WARNING: The program will also run using the C implementation of jq but the results for the very
large values will be inaccurate.
 
'''Generic utility functions'''
<syntaxhighlight lang=jq>
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
# Input: a string in base $b (2 to 35 inclusive)
# Output: the decimal value
def frombase($b):
def decimalValue:
if 48 <= . and . <= 57 then . - 48
elif 65 <= . and . <= 90 then . - 55 # (10+.-65)
elif 97 <= . and . <= 122 then . - 87 # (10+.-97)
else "decimalValue" | error
end;
reduce (explode|reverse[]|decimalValue) as $x ({p:1};
.value += (.p * $x)
| .p *= $b)
| .value ;
</syntaxhighlight>
'''Base58Check'''
<syntaxhighlight lang=jq>
# The base58check alphabet, i.e. 0 => "1", etc
def alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
# input: a string in the specified $base
def convertToBase58($base):
. as $hash
| {x: (if $base == 16 and ($hash|startswith("0x"))
then $hash[2:]|frombase(16)
else $hash|frombase($base)
end),
sb: [] }
| until (.x <= 0;
(.x % 58) as $r
| .sb += [alphabet[$r:$r+1]]
| .x |= (. - $r) / 58 )
| .sb | reverse | join("");
 
def hashes: [
"0x61",
"0x626262",
"0x636363",
"0x73696d706c792061206c6f6e6720737472696e67",
"0x516b6fcd0f",
"0xbf4f89001e670274dd",
"0x572e4794",
"0xecac89cad93923c02321",
"0x10c8511e"
];
 
def task:
def s: "25420294593250030202636073700053352635053786165627414518";
 
(s | "\(lpad(58))-> \(convertToBase58(10))" ),
(hashes[]
| [lpad(58), convertToBase58(16)] | join("-> ") ) ;
 
task
</syntaxhighlight>
{{output}}
<pre>
25420294593250030202636073700053352635053786165627414518-> 6UwLL9RisZVooooooooooooooooooooo
0x61-> 2g
0x626262-> a3gV
0x636363-> aPEr
0x73696d706c792061206c6f6e6720737472696e67-> 2cFupjhnEuPooooooooooooooooo
0x516b6fcd0f-> ABnLTmg
0xbf4f89001e670274dd-> 3SEo3LWLoMXoo
0x572e4794-> 3EFU7m
0xecac89cad93923c02321-> EJDM8drfX5mooo
0x10c8511e-> Rt5zm
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">const alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
 
function encodebase58(hsh::AbstractString, base::Integer=16)
Line 565 ⟶ 706:
"0x10c8511e"]
println("# $s\n -> ", encodebase58(s))
end</langsyntaxhighlight>
 
{{out}}
Line 590 ⟶ 731:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.51
 
import java.math.BigInteger
Line 629 ⟶ 770:
println("${hash.padEnd(56)} -> $b58")
}
}</langsyntaxhighlight>
 
{{out}}
Line 648 ⟶ 789:
{{libheader|bignum}}
This version takes in account the leading zeroes in hexadecimal representation. It accepts also arrays or sequences of bytes as input, taking in account the leading zero bytes as described in https://en.bitcoin.it/wiki/Base58Check_encoding#Base58_symbol_chart
<langsyntaxhighlight Nimlang="nim">import sequtils, strutils
import bignum
 
Line 703 ⟶ 844:
 
for h in Hashes:
echo h.alignLeft(MaxLength), " → ", h.toBase58</langsyntaxhighlight>
 
{{out}}
Line 718 ⟶ 859:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use Math::BigInt;
 
sub encode_base58 {
Line 750 ⟶ 891:
0xecac89cad93923c02321
0x10c8511e
);</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 766 ⟶ 907:
Slight variation from [[Bitcoin/public_point_to_address#Phix]] in that it accepts any length string (which can be binary or text).<br>
Includes leading zeroes, if you don't want that just comment out the three lines defining/using the integer lz.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">b58</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"</span>
function base58(string s)
string out = ""
<span style="color: #008080;">function</span> <span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
integer lz = length(s)
<span style="color: #004080;">string</span> <span style="color: #000000;">out</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
while 1 do
<span style="color: #004080;">integer</span> <span style="color: #000000;">lz</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
s = trim_head(s,'\0')
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
if length(s)=0 then exit end if
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\0'</span><span style="color: #0000FF;">)</span>
if out="" then lz -= length(s) end if
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
integer c = 0
<span style="color: #008080;">if</span> <span style="color: #000000;">out</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #000000;">lz</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for i=1 to length(s) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
c = c*256+s[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
s[i] = floor(c/58)
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">*</span><span style="color: #000000;">256</span><span style="color: #0000FF;">+</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
c = mod(c,58)
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">/</span><span style="color: #000000;">58</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">58</span><span style="color: #0000FF;">)</span>
out &= b58[c+1]
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end while
<span style="color: #000000;">out</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">b58</span><span style="color: #0000FF;">[</span><span style="color: #000000;">c</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
out &= repeat('1',lz)
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
return reverse(out)
<span style="color: #000000;">out</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lz</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">out</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
?base58(x"00010966776006953D5567439E5E39F86A0D273BEED61967F6")
?base58(x"61") -- == base58("a")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"00010966776006953D5567439E5E39F86A0D273BEED61967F6"</span><span style="color: #0000FF;">)</span>
?base58(x"626262") -- == base58("bbb")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"61"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- == base58("a")</span>
?base58(x"636363") -- == base58("ccc")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"626262"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- == base58("bbb")</span>
?base58(x"73696d706c792061206c6f6e6720737472696e67")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"636363"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- == base58("ccc")</span>
-- ^ == base58("simply a long string")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"73696d706c792061206c6f6e6720737472696e67"</span><span style="color: #0000FF;">)</span>
?base58(x"516b6fcd0f")
<span style="color: #000080;font-style:italic;">-- ^ == base58("simply a long string")</span>
?base58(x"bf4f89001e670274dd")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"516b6fcd0f"</span><span style="color: #0000FF;">)</span>
?base58(x"572e4794")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"bf4f89001e670274dd"</span><span style="color: #0000FF;">)</span>
?base58(x"ecac89cad93923c02321")
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"572e4794"</span><span style="color: #0000FF;">)</span>
?base58(x"10c8511e")</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"ecac89cad93923c02321"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">base58</span><span style="color: #0000FF;">(</span><span style="color: #008000;">x"10c8511e"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 811 ⟶ 955:
"Rt5zm"
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">main =>
Tests = [[25420294593250030202636073700053352635053786165627414518,"6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"],
["0x61","2g"],
["0x626262", "a3gV"],
["0x636363", "aPEr"],
["0x73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"],
["0x516b6fcd0f", "ABnLTmg"],
["0xbf4f89001e670274dd", "3SEo3LWLoPntC"],
["0x572e4794", "3EFU7m"],
["0xecac89cad93923c02321", "EJDM8drfXA6uyA"],
["0x10c8511e", "Rt5zm"]],
foreach([Test,Check] in Tests)
Res = base58Check(Test),
printf("%-56w -> %w (%s)\n", Test, Res, cond(Res==Check,"ok", "not ok"))
end,
nl.
 
base58Check(Hash) = Out.reverse =>
CodeS = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
(string(Hash) -> X = Hash.to_int ; X = Hash),
Out = "",
while (X > 0)
Rem = X mod 58,
X := X // 58,
Out := Out ++ [CodeS[Rem+1]]
end.</syntaxhighlight>
 
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM (ok)
0x61 -> 2g (ok)
0x626262 -> a3gV (ok)
0x636363 -> aPEr (ok)
0x73696d706c792061206c6f6e6720737472696e67 -> 2cFupjhnEsSn59qHXstmK2ffpLv2 (ok)
0x516b6fcd0f -> ABnLTmg (ok)
0xbf4f89001e670274dd -> 3SEo3LWLoPntC (ok)
0x572e4794 -> 3EFU7m (ok)
0xecac89cad93923c02321 -> EJDM8drfXA6uyA (ok)
0x10c8511e -> Rt5zm (ok)</pre>
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(setq *B58Alpha
(chop "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") )
(de b58 (S)
Line 827 ⟶ 1,012:
(println (b58 "25420294593250030202636073700053352635053786165627414518"))
(println (b58 "0x626262"))
(println (b58 "0x636363"))</langsyntaxhighlight>
{{out}}
<pre>
Line 837 ⟶ 1,022:
=={{header|Python}}==
===Procedural===
===Works with Python 3.9
{{trans|C#}}
<langsyntaxhighlight lang="python">ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
 
def convertToBase58(num):
Line 845 ⟶ 1,031:
r = num % 58
sb = sb + ALPHABET[r]
num = num // 58;
return sb[::-1]
 
s = 25420294593250030202636073700053352635053786165627414518
b = convertToBase58(s)
print ("%-56d -> %s" % (s, b))
 
hash_arr = [0x61, 0x626262, 0x636363, 0x73696d706c792061206c6f6e6720737472696e67, 0x516b6fcd0f, 0xbf4f89001e670274dd, 0x572e4794, 0xecac89cad93923c02321, 0x10c8511e]
for num in hash_arr:
b = convertToBase58(num)
print ("0x%-54x -> %s" % (num, b))</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 870 ⟶ 1,056:
===Composition of pure functions===
{{Works with|Python|3.7}}
<langsyntaxhighlight lang="python">'''Base 58 check encoding'''
 
from functools import reduce
Line 1,030 ⟶ 1,216:
# MAIN ---
if __name__ == '__main__':
main()</langsyntaxhighlight>
{{Out}}
<pre>Base 58 check encoding:
Line 1,047 ⟶ 1,233:
=={{header|Quackery}}==
 
<langsyntaxhighlight Quackerylang="quackery"> [ table ] is base58char ( n --> n )
$ "123456789ABCDEFGHJKLMNPQRSTUV"
Line 1,073 ⟶ 1,259:
 
witheach [ base58$ echo$ cr ]
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,092 ⟶ 1,278:
=={{header|Racket}}==
(Examples from some other task)
<langsyntaxhighlight lang="racket">#lang racket
 
(define ((base-n-alphabet-encode alphabet) hash-string (in-base 16))
Line 1,118 ⟶ 1,304:
"0x572e4794"
"0xecac89cad93923c02321"
"0x10c8511e")))</langsyntaxhighlight>
{{out}}
<pre>"6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM"
Line 1,125 ⟶ 1,311:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>sub encode_Base58 ( Int $x ) {
constant @codes = <
1 2 3 4 5 6 7 8 9
Line 1,151 ⟶ 1,337:
is encode_Base58(.key), .value, "{.key} encodes to {.value}";
}
</syntaxhighlight>
</lang>
 
=={{header|REXX}}==
Line 1,159 ⟶ 1,345:
I get the result expected there.
Apart for the leading 1 the program works also for the inputs shown above.
<langsyntaxhighlight lang="rexx">/* REXX */
s="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
Numeric Digits 100
Line 1,171 ⟶ 1,357:
End
o=o||substr(s,1,1)
Say reverse(o)</langsyntaxhighlight>
{{out}}
<pre>16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM</pre>
===version 2===
does what the others do
<langsyntaxhighlight lang="rexx">/* REXX */
s="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
Numeric Digits 1000
Line 1,211 ⟶ 1,397:
Say 'found :' o
End
Return</langsyntaxhighlight>
{{out}}
<pre>expected: check_error_handlimng
Line 1,223 ⟶ 1,409:
 
The algorithm used doesn't need to &nbsp; ''reverse'' &nbsp; the residual string &nbsp; (it uses &nbsp; ''prepend'' &nbsp; instead of &nbsp; ''append'').
<langsyntaxhighlight lang="rexx">/*REXX pgm encodes a checksum (hash digest) into Base58 (the standard Bitcoin alphabet).*/
/* 0─────────────────I─────O────────────────────l──────────────── ◄───omit.*/
call B58 25420294593250030202636073700053352635053786165627414518
@= space(" 123456789ABCDEFGH JKLMN PQRSTUVWXYZabcdefghi jkmnopqrstuvwxyz", 0)
call B58 '61'x
numeric digits 500 /*just in case there're huge numberss. */
call B58 '626262'x
say B58(25420294593250030202636073700053352635053786165627414518)
call B58 '636363'x
say B58('61'x) ; say B58('626262'x)
call B58 '73696d706c792061206c6f6e6720737472696e67'x
say B58('636363'x) ; say B58('73696d706c792061206c6f6e6720737472696e67'x)
call B58 '516b6fcd0f'x
callsay B58('516b6fcd0f'x) ; say B58('bf4f89001e670274dd'x)
say B58('572e4794'x) ; say B58('ecac89cad93923c02321'x)
call B58 '572e4794'x
callsay B58 ('ecac89cad93923c0232110c8511e'x)
exit 0 /*stick a fork in it, we're all done. */
call B58 '10c8511e'x
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
B58: parse arg z 1 oz,,$; L1= 0; hx hex= 0; if numeric digits 500z='' then return /*for hugeZ nums.missing?*/
if \datatype(z=, 'W') | then return arg()>1 then do; hex= 1; z= c2d(z); end /*Is Z missingin hex? */
if \datatypeleft(z, 'W'1) | arg()>==1 then hxL1=1; verify(z ., if1) hx- then z=c2d(z)1 /*iscount Znumber inof hexleading ?ones (1's)*/
do until z==0; $= substr(@, z//58 +1, 1)$; z= z % 58
if left(z, 1)==1 then L1=verify(z ., 1) -1 /*count number of leading 1's (ones). */
/* 0─────────────────I─────O────────────────────l──────────────── ◄───omit.*/
@=space(" 123456789ABCDEFGH JKLMN PQRSTUVWXYZabcdefghi jkmnopqrstuvwxyz", 0)
$=
do until z=0; $=substr(@, z//58 +1, 1)$; z=z % 58
end /*until*/
if hxhex then oz= "'"c2x(oz)"'x" /*Original arg in hex? Transform Then transformit.*/
sayreturn right(oz, 60) '"───►'" left('', L1, 0)$ /*displayfor givenshowing argumentarg &and the residual. */
 
return /* [↑] also prepend residual with 1's.*/</lang>
</syntaxhighlight>
{{out|output}}
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
25420294593250030202636073700053352635053786165627414518 ───► 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 1,260 ⟶ 1,442:
'ECAC89CAD93923C02321'x ───► 000EJDM8drfXA6uyA
'10C8511E'x ───► Rt5zm
</pre>
 
=={{header|RPL}}==
Binary numbers cannot exceed 64 bits in RPL.
{{works with|HP|48G}}
« "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" → alphabet
« "" 1
'''IF''' 3 PICK TYPE 10 == '''THEN''' SF '''ELSE''' CF '''END'''
'''WHILE''' SWAP #0 DUP2 + ≠ '''REPEAT'''
58
'''IF''' 1 FS? '''THEN''' / LASTARG 3 PICK * - B→R SWAP
'''ELSE''' MOD LASTARG / IP '''END'''
alphabet ROT 1 + DUP SUB
ROT +
'''END''' DROP
» » '<span style="color:blue">→B58</span>' STO <span style="color:grey">''@ ( n or #n → "code" }''</span>
« { 6946892355 #61 #626262 #636363 #516B6FCD0F #572E4794 #10C8511E }
1 « <span style="color:blue">→B58</span> » DOLIST
» '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
1: { "Base58" "2g" "a3gV" "aPEr" "ABnLTmg" "3EFU7m" "Rt5zm" }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
nums = [25420294593250030202636073700053352635053786165627414518,
0x61,
Line 1,276 ⟶ 1,481:
 
puts nums.map{|n| n.digits(58).reverse.map{|i| ALPHABET[i]}.join}
</syntaxhighlight>
</lang>
{{out}}
<pre>6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 1,292 ⟶ 1,497:
=={{header|Scala}}==
{{Out}}Best seen in running your browser either by [https://scalafiddle.io/sf/GMcrlBB/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">import java.math.BigInteger
object Base58 extends App {
Line 1,344 ⟶ 1,549:
}
 
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 1,350 ⟶ 1,555:
the function [http://seed7.sourceforge.net/libraries/encoding.htm#toBase(in_bigInteger,in_string) toBase],
which encodes a number with a positional numeric system. No external library is needed.
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "encoding.s7i";
 
Line 1,367 ⟶ 1,572:
writeln("16#" <& num radix 16 rpad 53 <& " -> " <& b);
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 1,383 ⟶ 1,588:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func encode_base58(n) {
static chars = %w(
1 2 3 4 5 6 7 8 9
Line 1,403 ⟶ 1,608:
printf("%56s -> %s\n", num, encode_base58(num))
assert_eq(encode_base58(num), enc)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,420 ⟶ 1,625:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Imports System.Numerics
Imports System.Text
 
Line 1,477 ⟶ 1,682:
End Sub
 
End Module</langsyntaxhighlight>
{{out}}
<pre>25420294593250030202636073700053352635053786165627414518 -> 6UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
Line 1,494 ⟶ 1,699:
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
import "./fmt" for Fmt
 
var alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
Line 1,529 ⟶ 1,734:
var b58 = convertToBase58.call(hash, 16)
Fmt.print("$-56s -> $s", hash, b58)
}</langsyntaxhighlight>
 
{{out}}
Line 1,547 ⟶ 1,752:
=={{header|zkl}}==
Uses libGMP
<langsyntaxhighlight lang="zkl">var [const] BN=Import.lib("zklBigNum"), // GNU Multiple Precision Arithmetic Library
src="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv",
dst="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
Line 1,559 ⟶ 1,764:
0x516b6fcd0f, "bf4f89001e670274dd", 0x572e4794,
"ecac89cad93923c02321", 0x10c8511e);
ns.pump(Console.println,'wrap(n){ BN(n,16).toString(58).translate(src,dst) });</langsyntaxhighlight>
{{out}}
<pre>
1,150

edits