1

関数からこの出力が得られるのはなぜですか?

echo $var = hash_hmac('ripemd160', 'http://www.weburlhere.org', 0, 0);
echo "\r\n";
echo $converted = base_convert($var, 16, 2);
echo "\r\n";

出力:

407a9d8868a678e12d9fc0264f9ae11e8761b557
0000000000000000000000000000000000000000000000000000000000000000

一方、base_convert($var, 16, 10)出力

1421821959848150668406846884086820088622688484226正しく。

また、副次的な質問として (これに対するボーナス ポイントです!) 私は、ripemd160 が入力プリイメージごとに一意の識別子を与えてくれると想定しています。URLを任意の長さからハッシュダイジェストに短縮するURL短縮サービスを作成しようとしています(バイナリをbase64に変換するbase64_encode($converted)と、URLがさらに短縮されると想定しています)。これは正しいですか、これは良い考えですか?

4

2 に答える 2

4

PHP のマニュアルによると、精度は 32 ビットまたは32 ビットbase_convert()に制限されています。ライブラリを使用して、任意の長さの数値を処理できます。doublefloatgmp

PHPマニュアルページからのサンプルコード:

/* use gmp library to convert base. gmp will convert numbers > 32bit
 * @author lindsay at bitleap dot com
 * @link you can execute this code at http://ideone.com/FT29qo
 */
function gmp_convert($num, $base_a, $base_b)
{
    return gmp_strval ( gmp_init($num, $base_a), $base_b );
}
于 2013-09-17T06:56:01.967 に答える
4

base_convertの PHP ドキュメントは言った

base_convert() は、使用される内部の「double」または「float」型に関連するプロパティが原因で、大きな数値の精度を失う可能性があります。より具体的な情報と制限については、マニュアルの浮動小数点数のセクションを参照してください。

したがって、この関数に頼って大きな数値を変換することはできません。ただし、基数 16 から基数 2 に変換する関数を手動で作成するのは非常に簡単です。

function hex2bin($hex) {
    $table = array('0000', '0001', '0010', '0011', 
                   '0100', '0101', '0110', '0111',
                   '1000', '1001', 'a' => '1010', 'b' => '1011', 
                   'c' => '1100', 'd' => '1101', 'e' => '1110', 
                   'f' => '1111');
    $bin = '';
    
    for($i = 0; $i < strlen($hex); $i++) {
        $bin .= $table[strtolower(substr($hex, $i, 1))];
    }
    
    return $bin;
}
echo hex2bin('407a9d8868a678e12d9fc0264f9ae11e8761b557');

base64_encode($converted) を使用してバイナリを base64 に変換すると、URL がさらに短縮されると想定しています)。これは正しいですか、これは良い考えですか

はい、短くなりました。2 進数の 32 分の 1、base-16 の 4 分の 1 です。ただし、ripemd160 は、すべてのリンクに一意の識別子を付与することを保証するものではありません。まだいくつかの衝突があります (それがどれほどまれかはわかりません)。

于 2013-09-17T06:41:20.377 に答える