Base58 Encoding and Decoding in PHP

A Detailed Guide to Base58 Encoding and Decoding in PHP

In this blog, we’ll dive into the world of Base58 encoding and decoding — a popular method used in various applications such as cryptocurrency addresses, IPFS, and URL shorteners. Specifically, we’ll focus on how to encode and decode hexadecimal strings into Base58 encoded strings, particularly the case where the output is restricted to 3 characters.

We’ll cover the underlying technical concepts, step-by-step instructions, and provide practical examples in PHP. Whether you’re building a cryptocurrency application or just curious about Base58 encoding, this guide will be useful.

What is Base58 Encoding?

Base58 encoding is a binary-to-text encoding scheme that encodes binary data into a string of ASCII characters, similar to Base64. However, Base58 avoids characters that can be easily confused with others (like the number 0, the letter O, the number 1, and the letter I), which helps in reducing errors when reading or typing the encoded strings.

The Base58 alphabet consists of the following characters:

123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

The primary use of Base58 encoding is found in cryptocurrency systems like Bitcoin, where it is used to encode public keys and wallet addresses.

Base58 Encoding Process

Base58 works by encoding 8-bit bytes into a set of 58 possible characters. It’s similar to Base64, but with a smaller set of characters, and is designed to avoid ambiguous characters.

Here’s the general procedure for encoding data into Base58:

  1. Convert the input data into a large integer.
  2. Divide the integer by 58, obtaining the quotient and remainder.
  3. The remainder corresponds to a character from the Base58 alphabet.
  4. Repeat the process with the quotient until the quotient becomes 0.
  5. The encoded string is the collection of characters corresponding to the remainders.

Decoding Base58

To decode a Base58 string, we reverse the encoding process:

  1. Convert the Base58 string back to an integer by using the reverse operation: each character is mapped to its position in the Base58 alphabet.
  2. After obtaining the integer, convert it back into a byte sequence.
  3. Convert the byte sequence back into the original data format (in our case, hexadecimal).

PHP Implementation of Base58 Encoding and Decoding

In this section, we will provide PHP functions to encode and decode hexadecimal strings into 3-character Base58 strings and vice versa.

Base58 Encoding Function

First, let’s create a function that converts a raw byte string into a Base58-encoded string.

// Base58 alphabet
$alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';

// Function to convert a number into Base58
function base58_encode($input) {
    global $alphabet;

    // Convert input string to an integer
    $num = gmp_init(bin2hex($input), 16);  // Treat input as hex and convert to GMP integer

    $base58 = '';
    while (gmp_cmp($num, 0) > 0) {
        list($num, $mod) = gmp_div_qr($num, 58);
        $base58 = $alphabet[gmp_intval($mod)] . $base58;
    }

    return $base58;
}
  • This function uses GMP (GNU Multiple Precision) arithmetic to handle very large numbers since Base58 encoding can result in numbers that exceed the normal integer range.
  • It converts the input string into hexadecimal and then treats it as a large integer.
  • The function repeatedly divides the number by 58, appending the corresponding Base58 character for the remainder until the quotient becomes zero.

Base58 Decoding Function

Now, let’s create the decoding function to reverse the Base58 encoding.

// Function to decode a Base58 string
function base58_decode($input) {
    global $alphabet;

    // Convert Base58 string to an integer
    $num = gmp_init(0);  // Initialize a large integer
    $base58_len = strlen($input);

    // Iterate through each character in the input string
    for ($i = 0; $i < $base58_len; $i++) {
        $char = $input[$i];
        $index = strpos($alphabet, $char);  // Find the character's index in the Base58 alphabet
        $num = gmp_add(gmp_mul($num, 58), $index);  // Multiply the number by 58 and add the index
    }

    // Convert the integer back to a hexadecimal string
    $hex = gmp_strval($num, 16);  // Convert to hexadecimal

    // Ensure it has an even number of characters (required for packing)
    if (strlen($hex) % 2 != 0) {
        $hex = '0' . $hex;
    }

    return $hex;
}
  • The decoding function takes a Base58 string and converts it into a large integer.
  • After decoding, the integer is converted back into a hexadecimal string, which is the original format.

Converting to a 3-Character Base58 Encoded String

We are specifically interested in encoding a hexadecimal string into 3-character Base58 strings. For that, we simply apply the base58_encode() function and trim the result to 3 characters.

// Function to convert a string (like '1000202020202342') to Base58 and get 3 characters
function convert_to_base58($str) {
    // Convert input string to bytes
    $input = pack('H*', $str);  // Pack the hex string into raw bytes

    // Get the Base58 encoding
    $encoded = base58_encode($input);

    // Trim the encoded string to 3 characters
    return substr($encoded, 0, 3);
}

Full Example with Encoding and Decoding

$input = '1000202020202342';  // Input hex string
$base58_str = convert_to_base58($input);  // Convert to 3-char Base58
echo "Encoded '$input' to 3 chars: $base58_str\n";

// Now decode the Base58 string back to hex
$decoded_hex = base58_decode($base58_str);
echo "Decoded Base58 '$base58_str' to hex: $decoded_hex\n";

Example Walkthrough

  1. Input Hex String: '1000202020202342'
  2. Base58 Encoded String: After running the above code, the Base58 encoded string of this hex string will be 4r1.
  3. Decoded Hex String: When decoding 4r1, we get back the original hexadecimal string 1000202020202342.

Handling Invalid Inputs

It’s important to ensure that the input is valid before encoding or decoding. In the PHP example, we used the ctype_xdigit() function to check whether a string is a valid hexadecimal string.

if (ctype_xdigit($input)) {
    // Valid hex string, proceed with encoding
} else {
    echo "Invalid hexadecimal string.\n";
}

Applications of Base58

Base58 encoding is widely used in several applications:

  • Cryptocurrency: For encoding wallet addresses and public keys.
  • URL shorteners: For generating unique, human-readable short URLs.
  • Data storage: In systems like IPFS, where large data needs to be referenced in a compact, unique format.

Conclusion

In this guide, we learned how to encode and decode hexadecimal strings using Base58 in PHP. We provided a step-by-step explanation, code snippets, and practical examples of how to work with Base58 encoding, including how to achieve 3-character Base58 encoded strings.

Understanding and implementing Base58 encoding is essential for various use cases, from cryptocurrencies to data storage systems, and knowing how to work with it in PHP will make it easier for you to integrate Base58 encoding into your projects.

Happy coding!

Crazy about CRO?

15+ ideas for growing your eCommerce store

Join & get tip & tricks for eCommerce Growth

We don’t spam! Read more in our privacy policy

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *