PHP 5.3〜
ネットワーク種別は、単純に頭文字をチェックするんでもOK。
$ composer require christian-riesen/base32
$ composer require izayoi256/keccak
require_once __DIR__ . '/vendor/autoload.php';
use Base32\Base32;
use izayoi256\Keccak;
define('NETWORK_ID_MAINNET', 104);
define('NETWORK_ID_MIJINNET', 96);
define('NETWORK_ID_TESTNET', -104);
function is_valid_address($address, array $networkIds = array())
{
if (!is_string($address)) {
throw new \InvalidArgumentException('Address must be string.');
// または
// return false;
}
if (!is_array($networkIds) || $networkIds !== array_filter($networkIds, 'is_int')) {
throw new \InvalidArgumentException('Network IDs must be an array of integer.');
}
$str = str_replace('-', '', $address);
if (strlen($str) !== 40) {
return false;
}
$decoded = bin2hex(Base32::decode($str));
$hash = substr($decoded, 0, 42);
// hex2bin()はPHP5.4以降のため、pack('H*', $var)を使用する。
$bin = pack('H*', $hash);
$checksum = substr(Keccak::hash($bin, 256), 0, 8);
if (substr($decoded, 42) !== $checksum) {
return false;
}
$networkValid = !count($networkIds);
foreach ($networkIds as $networkId) {
$hex = bin2hex(pack('c', $networkId));
$networkValid = $networkValid || preg_match("/^{$hex}/", $decoded);
}
return $networkValid;
}
// アドレスの有効性をチェックする
is_valid_address('TCY3JIKAYRUPEFDAJUZX7TPOOV6M22E4YU6R42RI');
// TRUE
// アドレスの有効性と、ネットワーク種別をチェックする
is_valid_address('TCY3JIKAYRUPEFDAJUZX7TPOOV6M22E4YU6R42RI', array(NETWORK_ID_MAINNET));
// FALSE