2

Instapaper (テキストを保存するブックマークレット) がどのようにしてブックマークレットの URL を生成するのか気になります。

私のものには、似たようなスクリプトのsrcがありますwww.instapaper.com/j/AnJHrfoDTRia

これらの URL の品質は、決して衝突する必要がなく、実際に推測可能ではないことです (そのため、他の人があなたのアカウントに保存することはできません)。

メールアドレスをMD5するのが簡単な方法かもしれませんが(サインアップ時に一意性をチェックしたと思われます)、非常に長い文字列になってしまいます。これは大きな問題ではありませんが、あまり頻繁に衝突しない短い GUID にはどのような手法があるのだろうかと考えています (これは明らかにトレードオフですが、私の意見では、上記の 12 文字はかなり短いです)。

4

4 に答える 4

2

MD5 ハッシュを基数 16 (文字 (0-9a-f) を使用) の数値として扱い、それを基数 36 などに変換することで、より短い文字列を取得できます。

<?php
function gmp_convert($num, $base_a, $base_b) {
    return gmp_strval (gmp_init($num, $base_a), $base_b );
}

$hash = md5("hello");
$hash2 = gmp_convert($hash,16,36);
echo "$hash <br>"; //5d41402abc4b2a76b9719d911017c592 
echo $hash2; //5ir3t0ozoelrnauhrwyu1xfgy

あなたが言及したリンクは、すべての文字(大文字と小文字)を使用しているようです。

これらの Q&Aから抽出された情報

于 2011-01-11T04:39:02.807 に答える
0

Base64は、暗号的に強力な一連の乱数をエンコードします。

<?php
// get 72 pseudorandom bits in a base64 string of 12 characters

$pr_bits = '';

// Unix/Linux platform?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
    $pr_bits .= @fread($fp,9);
    @fclose($fp);
}

// MS-Windows platform?
if (@class_exists('COM')) {
    // http://msdn.microsoft.com/en-us/library/aa388176(VS.85).aspx
    try {
        $CAPI_Util = new COM('CAPICOM.Utilities.1');
        $pr_bits .= $CAPI_Util->GetRandom(9,0);

        // if we ask for binary data PHP munges it, so we
        // request base64 return value.  We squeeze out the
        // redundancy and useless ==CRLF by hashing...
        if ($pr_bits) { $pr_bits = substr(md5($pr_bits,TRUE), 0, 9); }
    } catch (Exception $ex) {
        // echo 'Exception: ' . $ex->getMessage();
    }
}

$uid = base64_encode($pr_bits);
?>

これにより、12 文字で最も純粋なコロンビア語の 72 ビットが得られます。このセットには、およそ 10^21 の数値が含まれています。これは、100 万人のユーザーが衝突する可能性が約 10 億分の 1 であることを意味します。

これは、crypto awesomeness を生成するためのこの stackoverflow の回答をわずかに変更したものです: PHP での乱数生成を保護します

于 2012-07-20T02:14:43.493 に答える
0
<?php

$length = 12;

$chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));

$hash = '';

for ($i = 0; $i < $length; $i++) {
    $hash .= $chars[array_rand($chars)];
}

var_dump($hash);

これにより、md5 の 281474976710656 に対して 3226266762397899821056 の一意の組み合わせが得られます (これは1100 万倍です)。

わずか 4 文字 (!!!) の場合、14776336 のユニークな組み合わせになり、これで十分です。

于 2011-01-11T04:42:53.700 に答える
-3

MD5 ユーザー名。結果の MD5 ハッシュの最初の X 文字を取得します。DB にその値を持つ URL トークンが既に存在するかどうかを確認します。もしそうなら、最初の X+1 文字を取り、それを試してください (等々)。そうでない場合は、そのユーザーのトークンがあります。トークンをDBに保存し、これからはそこを調べます。毎回ユーザー名からトークンを再作成しようとしないでください。

おそらく、X=7 から始めて問題なく実行できます (大多数のトークン生成で試行回数は 1 ~ 2 回まで)。

また、特定のユーザーのトークンを予測するのを難しくするために、ハッシュ計算に何か他のもの (たとえば、乱数) を追加することもできます。

于 2011-01-11T04:08:17.030 に答える