Php Base58编码Peercoin公钥的步骤

Php Base58编码Peercoin公钥的步骤,php,c++,Php,C++,我希望有人能帮助我应对这个挑战。我想知道转换文件的过程 将十六进制130字符Peercoin公钥转换为Peercoin地址。如果你能读C++,在这里阅读源代码,会有帮助。我需要帮助调整这个代码为Peercoin工作(我从这个网站上的前一个问题得到了这个代码)。 举个例子, 130个字符的公钥:04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E5374E573FA570D8EA94FC44905

我希望有人能帮助我应对这个挑战。我想知道转换文件的过程 将十六进制130字符Peercoin公钥转换为Peercoin地址。如果你能读C++,在这里阅读源代码,会有帮助。我需要帮助调整这个代码为Peercoin工作(我从这个网站上的前一个问题得到了这个代码)。 举个例子, 130个字符的公钥:04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E

上述设备的Base58编码对等接口地址为:PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe

注意:这是一个有效的公钥,我从中获得了该密钥,并使用PPCOIN对其进行了测试

    <?php 

function hexStringToByteString($hexString){
    $len=strlen($hexString);

    $byteString="";
    for ($i=0;$i<$len;$i=$i+2){
        $charnum=hexdec(substr($hexString,$i,2));
        $byteString.=chr($charnum);
    }

return $byteString;
}

// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $rep = '';

    while( true ){
        if( strlen($num) < 2 ) {
            if( intval($num) <= 0 ) {
                break;
            }
        }
        $rem = bcmod($num, $base);
        $rep = $basestr[intval($rem)] . $rep;
        $num = bcdiv(bcsub($num, $rem), $base);
    }
    return $rep;
}

function bc_arb_decode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $dec = '0';

    $num_arr = str_split((string)$num);
    $cnt = strlen($num);
    for($i=0; $i < $cnt; $i++) {
        $pos = strpos($basestr, $num_arr[$i]);
        if( $pos === false ) {
            Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
        }
        $dec = bcadd(bcmul($dec, $base), $pos);
    }
    return $dec;
}


// base 58 alias
function bc_base58_encode($num) {   
    return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
    return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}

//hexdec with BCmath
function bc_hexdec($num) {
    return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {

    return bc_arb_encode($num, '0123456789abcdef');
}

// step 1

$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';

$step1=hexStringToByteString($publickey);

//echo "step1 ".$step1."<br>";

// step 2

$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";

// step 3

$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";

// step 4

$step4='55'.$step3;
echo "step4 ".$step4."<br>";

// step 5

$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";

// step 6

// $step6=hash("sha256",hexStringToByteString($step5));
// echo "step6 ".$step6."<br>";

// step 7

$checksum=substr($step5,0,8);
echo "step7 ".$checksum."<br>";

// step 8

$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";




// step 9
// base conversion is from hex to base58 via decimal. 
// Leading hex zero converts to 1 in base58 but it is dropped
// in the intermediate decimal stage.  Simply added back manually.

$step9='P'.bc_base58_encode(bc_hexdec($step8));
echo "step9 ".$step9."<br><br>";

?> 

好的!最后我自己解决了这个问题。最大的问题是我用55作为十进制,而我本应该把55转换成十六进制,也就是“37”。我还收回了我对PPC的评论,只使用sha256而不是sha256d。公钥的base58编码方式与比特币相同,但不是使用版本号1,而是55,十六进制的55是37(我在上面提到过)。这是最后的代码和输出

干杯

    <?php 

function hexStringToByteString($hexString){
    $len=strlen($hexString);

    $byteString="";
    for ($i=0;$i<$len;$i=$i+2){
        $charnum=hexdec(substr($hexString,$i,2));
        $byteString.=chr($charnum);
    }

return $byteString;
}

// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $rep = '';

    while( true ){
        if( strlen($num) < 2 ) {
            if( intval($num) <= 0 ) {
                break;
            }
        }
        $rem = bcmod($num, $base);
        $rep = $basestr[intval($rem)] . $rep;
        $num = bcdiv(bcsub($num, $rem), $base);
    }
    return $rep;
}

function bc_arb_decode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $dec = '0';

    $num_arr = str_split((string)$num);
    $cnt = strlen($num);
    for($i=0; $i < $cnt; $i++) {
        $pos = strpos($basestr, $num_arr[$i]);
        if( $pos === false ) {
            Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
        }
        $dec = bcadd(bcmul($dec, $base), $pos);
    }
    return $dec;
}


// base 58 alias
function bc_base58_encode($num) {   
    return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
    return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}

//hexdec with BCmath
function bc_hexdec($num) {
    return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {

    return bc_arb_encode($num, '0123456789abcdef');
}


$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';

//step1 is just converting the 130-hex-character publickey in bytes
$step1=hexStringToByteString($publickey);

echo "step1 ".$publickey."<br>";

// step 2 sha256 hashes the publickey from step 1

$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";

// step 3 ripemd160 hashes step2

$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";

// step 4 is the tricky part: add 37(hexadecimal of 55)the
// version number to step 3

$step4='37'.$step3;
echo "step4 ".$step4."<br>";

// step 5 sha256 hash step4 

$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";

// step 6 sha256 hash step 5

$step6=hash("sha256",hexStringToByteString($step5));
echo "step6 ".$step6."<br>";

// step 7 takes the first 8 characters (4 bytes) of step 6 as a checksum

$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";

// step 8 adds the checksum to step 4

$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";


//step 9 converts step 8 into decimal
$step9=bc_hexdec($step8);


//step 10 encodes step 9 into base58
$step10=bc_base58_encode($step9);
echo "step9 ".$step10."<br><br>";

?>

正如你可能看到的,它们是匹配的

你知道第一个错误大概发生在哪里吗?知道散列步骤是否正确吗?@ChristopherRoicles,不,这是我的问题,但我认为到第4步为止,这个过程是正确的。我不太熟悉C++,所以我不确定开发人员是如何设计哈希过程的。另外,我想指出的是,这段代码对于比特币公钥的编码非常有效(将'55'更改为'0'),因此由于Peercoin是基于比特币的,我认为这个过程是类似的。好吧,我取得了一些进展。首先,我发现Peercoin不使用SHA256D,它只使用SHA256,这意味着它不会对ripemd160进行双重哈希。因此,您可以看到,在代码中,我在步骤5和6之间对SHA256进行了双重哈希,这是一个错误。但是,即使我注释掉第二个SHA256哈希并继续处理,我仍然得到了错误的编码公钥地址。。。
    <?php 

function hexStringToByteString($hexString){
    $len=strlen($hexString);

    $byteString="";
    for ($i=0;$i<$len;$i=$i+2){
        $charnum=hexdec(substr($hexString,$i,2));
        $byteString.=chr($charnum);
    }

return $byteString;
}

// BCmath version for huge numbers
function bc_arb_encode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $rep = '';

    while( true ){
        if( strlen($num) < 2 ) {
            if( intval($num) <= 0 ) {
                break;
            }
        }
        $rem = bcmod($num, $base);
        $rep = $basestr[intval($rem)] . $rep;
        $num = bcdiv(bcsub($num, $rem), $base);
    }
    return $rep;
}

function bc_arb_decode($num, $basestr) {
    if( ! function_exists('bcadd') ) {
        Throw new Exception('You need the BCmath extension.');
    }

    $base = strlen($basestr);
    $dec = '0';

    $num_arr = str_split((string)$num);
    $cnt = strlen($num);
    for($i=0; $i < $cnt; $i++) {
        $pos = strpos($basestr, $num_arr[$i]);
        if( $pos === false ) {
            Throw new Exception(sprintf('Unknown character %s at offset %d', $num_arr[$i], $i));
        }
        $dec = bcadd(bcmul($dec, $base), $pos);
    }
    return $dec;
}


// base 58 alias
function bc_base58_encode($num) {   
    return bc_arb_encode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}
function bc_base58_decode($num) {
    return bc_arb_decode($num, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
}

//hexdec with BCmath
function bc_hexdec($num) {
    return bc_arb_decode(strtolower($num), '0123456789abcdef');
}
function bc_dechex($num) {

    return bc_arb_encode($num, '0123456789abcdef');
}


$publickey='04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E';

//step1 is just converting the 130-hex-character publickey in bytes
$step1=hexStringToByteString($publickey);

echo "step1 ".$publickey."<br>";

// step 2 sha256 hashes the publickey from step 1

$step2=hash("sha256",$step1);
echo "step2 ".$step2."<br>";

// step 3 ripemd160 hashes step2

$step3=hash('ripemd160',hexStringToByteString($step2));
echo "step3 ".$step3."<br>";

// step 4 is the tricky part: add 37(hexadecimal of 55)the
// version number to step 3

$step4='37'.$step3;
echo "step4 ".$step4."<br>";

// step 5 sha256 hash step4 

$step5=hash("sha256",hexStringToByteString($step4));
echo "step5 ".$step5."<br>";

// step 6 sha256 hash step 5

$step6=hash("sha256",hexStringToByteString($step5));
echo "step6 ".$step6."<br>";

// step 7 takes the first 8 characters (4 bytes) of step 6 as a checksum

$checksum=substr($step6,0,8);
echo "step7 ".$checksum."<br>";

// step 8 adds the checksum to step 4

$step8=$step4.$checksum;
echo "step8 ".$step8."<br>";


//step 9 converts step 8 into decimal
$step9=bc_hexdec($step8);


//step 10 encodes step 9 into base58
$step10=bc_base58_encode($step9);
echo "step9 ".$step10."<br><br>";

?>
step1 04D166177BBC050D53ABD5197A1A0D1DAC31B14795E0A1C2267918FBEAF28DDCBB200D313541E8E5374E573FA570D8EA94FC44905243FAC2726D625C11A36C9A3E
step2 6cf59dae61a5b2a4ca2990c644fa7d444928175f1c454f0cf2f4d98081dc6f63
step3 c07de396ef663b22ccab46fc87d067eaad408aa3
step4 37c07de396ef663b22ccab46fc87d067eaad408aa3
step5 a4237928cd0a9cbb001325a9b4726633ed67fd0ce15bf50c7d19260a297f488b
step6 443e1443a9fbdc855b88865e621fc5b35fe4515bc35229460ccb9f277dd35c21
step7 443e1443
step8 37c07de396ef663b22ccab46fc87d067eaad408aa3443e1443
step9 PS8yhj8NjXpJG4AFx77AYjpS2DZ8ucCGJe