web-dev-qa-db-ja.com

MD5ハッシュを整数として表す

ユーザーデータベーステーブルでは、ユーザーの電子メールアドレスのMD5ハッシュをIDとして使用します。

例:email([email protected]) = id(d41d8cd98f00b204e9800998ecf8427e)

残念ながら、IDを整数値として表す必要があります。IDが整数のみであるAPIを使用できるようにするためです。

今、私はIDを整数にエンコードして、受信時にデコードを再度送信する方法を探しています。どうすればこれを行うことができますか?

これまでの私の考え:

  1. MD5ハッシュの場合はconvert_uuencode()およびconvert_uudecode()
  2. mD5ハッシュのすべての文字をそのord()値で置き換えます

どちらのアプローチが良いですか?これを行うためのさらに良い方法を知っていますか?

あなたが私を助けてくれることを願っています。事前にどうもありがとうございました!

17
caw

注意してください。 MD5を整数に変換するには、大きな(128ビット)整数のサポートが必要になります。使用しているAPIが32ビット整数のみをサポートする可能性があります。さらに悪いことに、浮動小数点の数値を処理している可能性があります。いずれにせよ、あなたのIDは変更されます。この場合、MD5を整数に変換するよりも、2番目のIDを任意に割り当てる方がはるかに優れた方法です。

ただし、APIが問題なく任意の大きな整数を処理できることが確実である場合は、MD5を16進数から整数に変換するだけです。 PHPは、この組み込みをサポートしていない可能性がありますが、32ビット整数または浮動小数点として表現しようとするため、おそらく-を使用する必要があります。 PHP GMPライブラリ そのため。

17
bdonlan

他の人が述べているように、それを別の方法で行うのには正当な理由があります。

しかし、あなたがしたいのがmd5ハッシュを10進数の文字列に変換することである場合(これは、md5がすでに整数であるため、「整数で表す」という意味だと思います。文字列形式)、それを同じmd5文字列に変換し直します。

function md5_hex_to_dec($hex_str)
{
    $arr = str_split($hex_str, 4);
    foreach ($arr as $grp) {
        $dec[] = str_pad(hexdec($grp), 5, '0', STR_PAD_LEFT);
    }
    return implode('', $dec);
}

function md5_dec_to_hex($dec_str)
{
    $arr = str_split($dec_str, 5);
    foreach ($arr as $grp) {
        $hex[] = str_pad(dechex($grp), 4, '0', STR_PAD_LEFT);
    }
    return implode('', $hex);
}

デモ:

$md5 = md5('[email protected]');
echo $md5 . '<br />';  // 23463b99b62a72f26ed677cc556c44e8
$dec = md5_hex_to_dec($md5);
echo $dec . '<br />';  // 0903015257466342942628374306682186817640
$hex = md5_dec_to_hex($dec);
echo $hex;             // 23463b99b62a72f26ed677cc556c44e8

もちろん、どちらかの文字列を使用する場合は注意が必要です。たとえば、先行ゼロが失われないように文字列型としてのみ使用するようにしたり、文字列が正しい長さであることを確認したりする必要があります。

10
GZipp

32ビットの凝縮の場合、MD5ハッシュの4つの16進ペア(8文字)を選択し、各ペアが1バイトを表し、それを intval()で変換することによって簡単な解決策を作成できます。

符号なし32ビットIntの場合:

$inthash = intval(substr(md5($str), 0, 8), 16);

符号付き32ビットIntの正の値の場合:

$inthash = intval(substr(md5($str), 0, 8), 16) >> 1;

これは、ドキュメントに記載されているように、最新のシステムのほとんどで64ビット(8バイトまたは16文字)までの値でのみ機能する可能性があります。

64ビットIntに対応できるシステムでは、128ビットMD5ハッシュ全体を2Intとして消費する分割戦略は次のようになります。

$hash = md5($str);
$inthash1 = intval(substr($hash, 0, 16), 16);
$inthash2 = intval(substr($hash, 16, 16), 16);
7
codebard

なぜord()? md5は通常の16バイト値を生成し、読みやすくするために16進数で表示されます。したがって、16バイトの値を損失なしに4バイトまたは8バイトの整数に変換することはできません。これをidとして使用するには、アルゴリズムの一部を変更する必要があります。

2
Alexey Sviridov

hexdec を使用して、16進文字列を解析し、その数値をデータベースに格納できます。

1
Malax

自動インクリメントのintフィールドである別のフィールドを追加することはできませんか?

1
SeanJA

どうですか:

$ float = hexdec(md5( 'string'));

または

$ int =(integer)(substr(hexdec(md5( 'string'))、0,9)* 100000000);

衝突の可能性は間違いなく大きいですが、DBでハッシュの代わりに使用するのは十分ですか?

乾杯、

/マルシン

1
Marcin

/var/myprocess/[email protected]のように、共有フォルダー内の空白の一時ファイルのファイル名として電子メールアドレスを使用します

次に、ファイル名でftokを呼び出します。 ftokは一意の整数IDを返します。

一意であることが保証されるわけではありませんが、APIにはおそらく十分です。

0
humbads