'''[https://tools.ietf.org/id/draft-msporny-base58-02.txt%|%base58]''' is like [base64], but without these characters: `+/0OIl` ** See Also ** [ycl%|%ycl string base encode/decode]: Encodes and decodes [binary%|%bytes] using the given list of encoding characters. ** Description ** base58 is used in the bitcoin system, and there is apparently a different version of base58 used by Flickr. The rationale behind the use of base58, at least for bitcoin, is: * Characters like `0` and `O`, or `I` and `l` are too similar in some fonts and could be used to create account numbers that are hard to distinguish visually. * A string with non-alphanumeric characters is not as easily accepted as an account number. * E-mail content isn't broken into lines where there's no punctuation to break at. * Doubleclicking selects the whole number as one word if it's all alphanumeric. The alphabet used is: `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`. ---- [JMN] 2011-06-28: Does anyone know if there are existing Tcl implementations of base58 as used by bitcoin? ---- '''[AK] - 2011-06-28 17:41:27''' I do not know of any implementation. If one is made by whoever I would strongly recommend to submit the code to Tcllib for inclusion, as it already has base64, base32, ascii85, uu, yEnc, etc. I.e. a base58 implementation would fit right in. ---- [aspect]: this came up in the [Tcl Chatroom] so I did a quick implementation. base58 is not so good for encoding binary chunks, as it doesn't correspond neatly to a length in bits. This version base58-encodes an integer: ====== proc base58 {hex} { set alphabet 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz set result {}; scan $hex %llx int; set alen [string length $alphabet] while {$int} { set result [string index $alphabet [expr {$int%$alen}]]$result set int [expr {$int/$alen}] } set result } ====== [AvL]: I changed the name of the previous example to "base58", fixed a reversal bug and made it take a hexadecimal string to match later usage samples on this page. For bitcoin-related use, here's another snippet that extracts the address from a scriptPub: ====== package require sha256 set scriptPubKey "76a9146ccf14fa32539e2d148a3b39d87ae0e7c6f17b5988ac" if {[regexp {^76a914([0-9a-f]{40})88ac$} $scriptPubKey _ xpub]} { set xpub 00$xpub set bpub [binary format H* $xpub] set sha [sha2::sha256 [sha2::sha256 -bin $bpub]] set num 1[base58 $xpub[string range $sha 0 7]] } ====== Maybe we ought to open a separate page for bitcoin-stuff in Tcl, once it becomes more than just base58 and a usage sample. An example usage to generate unique identifiers a la youtube might be: ====== package require md5 string range [base58 [md5::md5 -hex myidentifier]] 0 11 ====== Whether your identifiers are sufficiently unique is a matter for you to decide .. Note that the only rationale for including [md5] is to make the distribution more uniform and obscure the source of identifiers. The md5 output is also being truncated to a number between 0 and 58**12, or: ====== tclsh8.5 [~]list [expr log(58**12)/log(2)] bits 70.29577194153087 bits ====== <> Cryptography | Internet | Bitcoin