Skip to content

Instantly share code, notes, and snippets.

@diafygi
Forked from 140bytes/LICENSE.txt
Last active November 20, 2023 20:59
Show Gist options
  • Save diafygi/90a3e80ca1c2793220e5 to your computer and use it in GitHub Desktop.
Save diafygi/90a3e80ca1c2793220e5 to your computer and use it in GitHub Desktop.
Base58 Encoder/Decoder - slightly over 140 bytes, but still pretty useful

140byt.es

A tweet-sized, fork-to-play, community-curated collection of JavaScript.

How to play

  1. Click the Fork button above to fork this gist.
  2. Modify all the files to according to the rules below.
  3. Save your entry and tweet it up!

Keep in mind that thanks to the awesome sensibilities of the GitHub team, gists are just repos. So feel free to clone yours and work locally for a more comfortable environment, and to allow commit messages.

Rules

All entries must exist in an index.js file, whose contents are

  1. an assignable, valid Javascript expression that
  2. contains no more than 140 bytes, and
  3. does not leak to the global scope.

All entries must also be licensed under the WTFPL or equally permissive license.

For more information

See the 140byt.es site for a showcase of entries (built itself using 140-byte entries!), and follow @140bytes on Twitter.

To learn about byte-saving hacks for your own code, or to contribute what you've learned, head to the wiki.

140byt.es is brought to you by Jed Schmidt, with help from Alex Kloss. It was inspired by work from Thomas Fuchs and Dustin Diaz.

var to_b58 = function(
B, //Uint8Array raw byte input
A //Base58 characters (i.e. "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
) {
var d = [], //the array for storing the stream of base58 digits
s = "", //the result string variable that will be returned
i, //the iterator variable for the byte input
j, //the iterator variable for the base58 digit array (d)
c, //the carry amount variable that is used to overflow from the current base58 digit to the next base58 digit
n; //a temporary placeholder variable for the current base58 digit
for(i in B) { //loop through each byte in the input stream
j = 0, //reset the base58 digit iterator
c = B[i]; //set the initial carry amount equal to the current byte amount
s += c || s.length ^ i ? "" : 1; //prepend the result string with a "1" (0 in base58) if the byte stream is zero and non-zero bytes haven't been seen yet (to ensure correct decode length)
while(j in d || c) { //start looping through the digits until there are no more digits and no carry amount
n = d[j]; //set the placeholder for the current base58 digit
n = n ? n * 256 + c : c; //shift the current base58 one byte and add the carry amount (or just add the carry amount if this is a new digit)
c = n / 58 | 0; //find the new carry amount (floored integer of current digit divided by 58)
d[j] = n % 58; //reset the current base58 digit to the remainder (the carry amount will pass on the overflow)
j++ //iterate to the next base58 digit
}
}
while(j--) //since the base58 digits are backwards, loop through them in reverse order
s += A[d[j]]; //lookup the character associated with each base58 digit
return s //return the final base58 string
}
var from_b58 = function(
S, //Base58 encoded string input
A //Base58 characters (i.e. "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
) {
var d = [], //the array for storing the stream of decoded bytes
b = [], //the result byte array that will be returned
i, //the iterator variable for the base58 string
j, //the iterator variable for the byte array (d)
c, //the carry amount variable that is used to overflow from the current byte to the next byte
n; //a temporary placeholder variable for the current byte
for(i in S) { //loop through each base58 character in the input string
j = 0, //reset the byte iterator
c = A.indexOf( S[i] ); //set the initial carry amount equal to the current base58 digit
if(c < 0) //see if the base58 digit lookup is invalid (-1)
return undefined; //if invalid base58 digit, bail out and return undefined
c || b.length ^ i ? i : b.push(0); //prepend the result array with a zero if the base58 digit is zero and non-zero characters haven't been seen yet (to ensure correct decode length)
while(j in d || c) { //start looping through the bytes until there are no more bytes and no carry amount
n = d[j]; //set the placeholder for the current byte
n = n ? n * 58 + c : c; //shift the current byte 58 units and add the carry amount (or just add the carry amount if this is a new byte)
c = n >> 8; //find the new carry amount (1-byte shift of current byte value)
d[j] = n % 256; //reset the current byte to the remainder (the carry amount will pass on the overflow)
j++ //iterate to the next byte
}
}
while(j--) //since the byte array is backwards, loop through it in reverse order
b.push( d[j] ); //append each byte to the result
return new Uint8Array(b) //return the final byte array in Uint8Array format
}
var to_b58 = function(B,A){var d=[],s="",i,j,c,n;for(i in B){j=0,c=B[i];s+=c||s.length^i?"":1;while(j in d||c){n=d[j];n=n?n*256+c:c;c=n/58|0;d[j]=n%58;j++}}while(j--)s+=A[d[j]];return s};
var from_b58 = function(S,A){var d=[],b=[],i,j,c,n;for(i in S){j=0,c=A.indexOf(S[i]);if(c<0)return undefined;c||b.length^i?i:b.push(0);while(j in d||c){n=d[j];n=n?n*58+c:c;c=n>>8;d[j]=n%256;j++}}while(j--)b.push(d[j]);return new Uint8Array(b)};
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "Base58EncodeDecode",
"description": "Encode a Uint8Array to a Base58 string, and decode a Base58 string to a Uint8Array",
"keywords": [
"Base58",
"Uint8Array",
"encode",
"decode",
"Bitcoin"
]
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script>
var MAP = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
var to_b58 = function(B,A){var d=[],s="",i,j,c,n;for(i in B){j=0,c=B[i];s+=c||s.length^i?"":1;while(j in d||c){n=d[j];n=n?n*256+c:c;c=n/58|0;d[j]=n%58;j++}}while(j--)s+=A[d[j]];return s};
var from_b58 = function(S,A){var d=[],b=[],i,j,c,n;for(i in S){j=0,c=A.indexOf(S[i]);if(c<0)return undefined;c||b.length^i?i:b.push(0);while(j in d||c){n=d[j];n=n?n*58+c:c;c=n>>8;d[j]=n%256;j++}}while(j--)b.push(d[j]);return new Uint8Array(b)};
var examples = [
new Uint8Array([1,183,12,45,131,11,153,200]),
new Uint8Array([0,0,0,0]),
new Uint8Array([255,255,255,255]),
new Uint8Array([0,1,2,3,4,5,6,7,8,9])
];
for(var e in examples){
var arr = [];
for(var i = 0; i < examples[e].length; i++)
arr.push(examples[e][i]);
var encoded = to_b58(examples[e], MAP);
var decoded = from_b58(encoded, MAP);
var decoded_arr = [];
for(var i = 0; i < decoded.length; i++)
decoded_arr.push(decoded[i]);
var result = document.createElement("p");
result.innerHTML = "" +
"Uint8Array([" + arr.toString() + "]) => " +
"'" + encoded + "' => " +
"Uint8Array([" + decoded_arr.toString() + "])";
document.getElementsByTagName("body")[0].appendChild(result);
}
</script>
</body>
</html>
@westonal
Copy link

westonal commented Oct 14, 2017

s += c || s.length ^ i ? "" : 1; //prepend the result string with a "1" (0 in base58) if the byte stream is zero and non-zero bytes haven't been seen yet (to ensure correct decode length)

Shouldn't you refer to the passed alphabet: A[0] rather than hardcode "1"

Also,

n = n ? n * 256 + c : c;

Isn't that just same as:?

n = n * 256 + c;

Or is that done due to a Javascript undefined thing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment