2012-10-18 27 views
2

我必須從增量數字(1到50000)和祕密密碼開始構建50,000個密碼。我必須在PHP中完成,最終代碼長度必須爲8或12個字符,並且只包含大寫字母(A-Z)和數字(0-9)。構建從數字和密碼開始的短密碼

最後的代碼必須爲解密與密碼...

我試圖用openssl_encrypt,但我不能找到一種方法,使「短」的最終代碼。

$longCode = openssl_encrypt($number, $method, ENC_KEY, true, $iv); 
$shortCode = ..... 

有些想法嗎?

+1

當您談論'密碼'時,我假設您希望能夠再次解密,對吧?你不是在尋找一個加密哈希函數?這在security.stackexchange中可能會更好。 – Joost

+0

首先,我想到了建議[Vigenènere密碼](http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher),但看到你的明文(數字從1到50k)是如此有限(和有序,在那)它變成一個弱caeser cypher ..你能發佈一些更多的要求? – Joost

+0

Joost是對的我希望能夠解密代碼。 – wildnove

回答

0

試試這個:

// generate random ID 
    function generateRandomID ($len) { 
     //To Pull Unique Random Values Out Of AlphaNumeric 
     //removed number 0, capital o, number 1 and small L 
     //Total: keys = 32, elements = 33 
     $characters = array(
     "A","B","C","D","E","F","G","H","J","K","L","M", 
     "N","P","Q","R","S","T","U","V","W","X","Y","Z", 
     "1","2","3","4","5","6","7","8","9"); 

     //make an "empty container" or array for our keys 
     $keys = array(); 

     //first count of $keys is empty so "1", remaining count is 1-6 = total 7 times 
     while(count($keys) < $len) { 
       //"0" because we use this to FIND ARRAY KEYS which has a 0 value 
       //"-1" because were only concerned of number of keys which is 32 not 33 
       //count($characters) = 33 
       $x = mt_rand(0, count($characters)-1); 
       if(!in_array($x, $keys)) { 
        $keys[] = $x; 
       } 
     } 

     foreach($keys as $key){ 
      $random_chars .= $characters[$key]; 
     } 
     return $random_chars; 
    } 

編輯:刪除一些字母和數字爲更好的方便用戶的閱讀,請在代碼中的註釋。

+0

當你有密碼時,它甚至可以遠程解密嗎? – Joost

+0

至於我讀到的問題,用戶需要一個函數來生成50000個隨機代碼,你的解密是什麼意思? – bodi0

+1

他正在生成基於整數和密碼的密碼。你不認爲他想用密碼解密密碼嗎?就像在共享密鑰加密協議中一樣?他沒有提到「隨機」這個詞。 – Joost

1

第一步是使用塊大小爲8字節的密碼方法,例如, 「RC2-CBC」。

$nr = 1234; 
$key = 'secretkey'; 
$method = 'rc2-cbc'; 

$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method)); 

$code = openssl_encrypt($nr, $method, $key, true, $iv); 

第二步是將結果字符串轉換爲字母;因爲你的字母大小隻有36,最接近和「容易」的轉換是base32;這給了(剝離可選填充之後)一串正好13個字符。

理論上你可以將4個字節爲base36的6個字:

log(36)/log(2) ~ 5.17 bits, saves 1 bit after 6 blocks 

6 x 5.17 ~ 31.02, 6 blocks fits inside 32 bits (unsigned long) 

32 bits = 4 bytes -> 6 characters 

故障實施

下面的代碼應該這樣做 - 但不(總是)工作!

$final = ''; 
foreach (str_split($code, 4) as $part) { 
    $x = current(unpack('L', $part)); 
    $final .= strtoupper(base_convert($x, 10, 36)); 
} 

解碼會是這樣的:

$code2 = ''; 
foreach (str_split($final, 6) as $part) { 
     $code2 .= pack('L', base_convert(strtolower($part), 36, 10)); 
} 

不知何故,精確到整數無法處理或我在做一些愚蠢的事;無論如何,它並不總是工作。

+0

13個字符...靠近解決方案...我必須保留12個字符。 – wildnove

+0

@wildnove管理,以適應它12個字符:) –

+0

你能告訴我如何解密代碼回數字? – wildnove