alphabet = $alphabet; $this->base = strlen($alphabet); } /** * Encode a string into base58. * * @param string $string The string you wish to encode. * @since Release v1.1.0 * @return string The Base58 encoded string. */ public function encode($string) { // Type validation if (is_string($string) === false) { throw new InvalidArgumentException('Argument $string must be a string.'); } // If the string is empty, then the encoded string is obviously empty if (strlen($string) === 0) { return ''; } // Strings in PHP are essentially 8-bit byte arrays // so lets convert the string into a PHP array $bytes = array_values(unpack('C*', $string)); // Now we need to convert the byte array into an arbitrary-precision decimal // We basically do this by performing a base256 to base10 conversion $decimal = $bytes[0]; for ($i = 1, $l = count($bytes); $i < $l; $i++) { $decimal = bcmul($decimal, 256); $decimal = bcadd($decimal, $bytes[$i]); } // This loop now performs base 10 to base 58 conversion // The remainder or modulo on each loop becomes a base 58 character $output = ''; while ($decimal >= $this->base) { $div = bcdiv($decimal, $this->base, 0); $mod = (int) bcmod($decimal, $this->base); $output .= $this->alphabet[$mod]; $decimal = $div; } // If there's still a remainder, append it if ($decimal > 0) { $output .= $this->alphabet[$decimal]; } // Now we need to reverse the encoded data $output = strrev($output); // Now we need to add leading zeros foreach ($bytes as $byte) { if ($byte === 0) { $output = $this->alphabet[0] . $output; continue; } break; } return (string) $output; } /** * Decode base58 into a PHP string. * * @param string $base58 The base58 encoded string. * @since Release v1.1.0 * @return string Returns the decoded string. */ public function decode($base58) { // Type Validation if (is_string($base58) === false) { throw new InvalidArgumentException('Argument $base58 must be a string.'); } // If the string is empty, then the decoded string is obviously empty if (strlen($base58) === 0) { return ''; } $indexes = array_flip(str_split($this->alphabet)); $chars = str_split($base58); // Check for invalid characters in the supplied base58 string foreach ($chars as $char) { if (isset($indexes[$char]) === false) { throw new InvalidArgumentException('Argument $base58 contains invalid characters. ($char: "'.$char.'" | $base58: "'.$base58.'") '); } } // Convert from base58 to base10 $decimal = $indexes[$chars[0]]; for ($i = 1, $l = count($chars); $i < $l; $i++) { $decimal = bcmul($decimal, $this->base); $decimal = bcadd($decimal, $indexes[$chars[$i]]); } // Convert from base10 to base256 (8-bit byte array) $output = ''; while ($decimal > 0) { $byte = (int) bcmod($decimal, 256); $output = pack('C', $byte) . $output; $decimal = bcdiv($decimal, 256, 0); } // Now we need to add leading zeros foreach ($chars as $char) { if ($indexes[$char] === 0) { $output = "\x00" . $output; continue; } break; } return $output; } }