簡體   English   中英

比哈希用戶ID短的GUID?

[英]Shorter GUIDs than hashing a user id?

我想知道Instapaper(保存文本的書簽)如何為其書簽生成URL。

我的腳本src類似於www.instapaper.com/j/AnJHrfoDTRia

這些URL的質量在於它們永遠不會發生沖突,並且也不應該讓人猜到(因此其他人無法保存到您的帳戶)。

我知道一種簡單的方法可能是將其電子郵件地址設置為MD5(假定已在注冊時進行了唯一性檢查),但是最后我得到了一個超長字符串。 這不是一個大問題,但是我想知道對於不經常發生沖突的較短GUID有什么技術(這顯然是一個權衡,但是我認為上面的12個字符很短)

您可以通過將MD5哈希值視為以16為底的數字(使用character(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

您提到的鏈接似乎使用了所有字母(大寫和小寫)。

這些問答中提取的信息

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萬用戶之后,發生碰撞的機會約為十億分之一。

這是此stackoverflow答案的非常細微的修改,用於生成加密效果: PHP中的安全隨機數生成

<?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);

這將使我們獲得3226266762397899821056獨特的組合,而md5則為281474976710656( 大於1100萬倍 )。

僅需4個字符(!!!),它將是14776336個獨特的組合,對您而言已經足夠。

MD5用戶名。 取所得的MD5哈希的前X個字符。 檢查數據庫中是否已存在具有該值的url令牌。 如果是這樣,請使用前X + 1個字符並嘗試使用該字符(依此類推)。 如果沒有,則您擁有該用戶的令牌。 從現在開始,將令牌存儲在數據庫中並在其中查找-不要嘗試每次都從用戶名重新創建令牌。

您可能以X = 7開始並做得很好(對於絕大多數代幣生成,嘗試不超過1-2次)。

另外,您可能想在哈希計算中添加其他內容(例如,它們的或隨機數),以使其更難以預測給定用戶的令牌。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM