作爲一名PHP程序員和C#編程初學者,我一直想知道生成獨特的串行數據的最佳方式,例如Microsoft Office和Microsoft操作系統的工作方式。使用PHP進行串行生成
有沒有人有一個很好的指導如何處理這一點,像什麼是生成獨特的序列,防止重複等重要因素如何創建/驗證它們的小例子。
這裏是我正在談論的RFC:http://tools.ietf.org/html/rfc1982。
作爲一名PHP程序員和C#編程初學者,我一直想知道生成獨特的串行數據的最佳方式,例如Microsoft Office和Microsoft操作系統的工作方式。使用PHP進行串行生成
有沒有人有一個很好的指導如何處理這一點,像什麼是生成獨特的序列,防止重複等重要因素如何創建/驗證它們的小例子。
這裏是我正在談論的RFC:http://tools.ietf.org/html/rfc1982。
如果您的應用程序有一個連接回到服務器,那麼只需生成隨機令牌,將它們存儲在數據庫中,並要求應用程序在運行前檢查服務器。但是有些客戶可能會發現這個要求是不可接受的。 (我個人絕不會與互聯網激活要求購買任何軟件,我想購買軟件,而不是把它租。)
對於真實性checkability鍵,而無需有一個連接到服務器:
在服務器上,生成一個隨機的唯一標記。
使用公鑰加密方案(例如RSA)使用對服務器保密的私鑰對令牌進行簽名。
使用一些二進制到文本方案(例如,base64或僅使用2-9A-KMNP-Z
符號以實現更安全的可打字性)將唯一標記和簽名一起編碼。編碼的組合是您的鑰匙或串行。
在應用程序的每個副本中嵌入與服務器私鑰匹配的公鑰,並在安裝時讓應用程序提示輸入密鑰。它可以拆分唯一標記和簽名,並使用公鑰來驗證簽名對該標記是否有效。
這種方法需要你捆綁一些加密庫與你的軟件,和大多數算法使用了相當長的簽名,爲了安全,這將使你的序列號,相當乏味的輸入,如果你希望用戶能夠複製它的確定並粘貼數字。
由於這些原因,許多軟件包使用不太安全的密鑰驗證方案,其中檢查算法完全內置於客戶端。這可能是一個散列,例如。串行的最後四個十六進制數字必須與串行其餘部分的SHA1散列的最低兩個字節匹配,並與「祕密」密鑰相結合。但是,由於密鑰必須捆綁在應用程序中,所以黑客可能會查看應用程序代碼並提取「祕密」密鑰,從而允許他們編寫自己的密鑰生成器。
這就是爲什麼對於某些程序,您會看到'keygens'可用:應用程序使用安全性較低的檢查算法,在應用程序中留下足夠的信息以允許cracker重新生成密鑰製作過程。對於基於公鑰密碼或互聯網激活的更安全設置的程序,您通常會看到應用程序的「破解」版本,而檢查代碼已被更改/刪除。
......哪種表現無論你做什麼,你仍然無法執行誠實。所以不要太擔心。
我不是很確定你想要什麼,但有http://www.php.net/manual/en/function.uniqid.php它創建唯一標識符。
如果您對它們的創建方式更感興趣,我建議您查看一下PHP源代碼,以瞭解uniqid是如何實現的。
林的問候交談http://tools.ietf.org/html/rfc1982 – RobertPitt 2010-09-10 20:13:28
uniqid是完全可以預見的。實際上,它只是它生成的microtime的一個代表。它絕不是隨機的。 – NikiC 2010-09-10 20:26:17
需要更多信息。你想創建一個序列鍵,比如你購買一款遊戲,或者你想要一個序列號作爲唯一的用戶ID。
序列號是否需要存儲過期時間/日期等信息?
@nikic - 所有rand的使用時間作爲啓動隨機生成器的基礎。這就是國防部使用熔岩燈的原因。他們有一個整個房間專用於熔岩燈和閃耀的激光,隨機創建一個獨特的鑰匙。
編輯:
那麼你需要考慮到影響的只是你的C#應用程序會用什麼方法與您的網站進行通信。
您將需要使用php創建一個密鑰並將其存儲在數據庫中,以便C#可以確認該串行是正確的。
然後您需要弄清楚PHP是否會返回另一個值,以便C#應用程序知道密鑰是否已通過身份驗證。
我在粘貼中做了什麼是創建一個公鑰和私鑰。公鑰將提供給用戶驗證產品。當他們驗證產品或登錄到系統時,將根據數據庫檢查公鑰,返回值將是私鑰。在與我的C#程序的所有交互過程中,如果用戶需要檢查更新或從我的服務器獲取信息,私鑰將被添加到服務器的查詢中,以確認最終用戶是合法的。
我還使用的另一種方法是上面的,但增加了額外的檢查以確認用戶不共享密鑰。 C#應用程序將獲得計算機中處理器的序列號,並在註冊該應用程序時將其保存到我的數據庫中。然後,如果有人試圖用相同的公鑰註冊產品但處理器的序列號不同,則會發出錯誤,他們需要聯繫支持人員。你可以這樣做,以允許5個不同的機器ID或每個你想要的。
創建註冊碼非常簡單,因爲您實際上只需要創建一個具有偏移量的隨機字符串(例如用戶名)。
但是,您也可以根據某人提供的名稱或公司名稱創建註冊碼,並將該算法添加到C#程序中。不利之處在於C#源代碼可以輕鬆地反編譯,可以發現該算法很容易創建註冊碼,而無需真正爲產品付費。通過添加身份驗證的服務器,對於某人來說,生成自己的序列密鑰要困難得多。
可以說我有一個產品,比如應用程序,這個應用程序需要一個串行系統,我想在PHP中生成一個可以在C#中進行檢查和驗證的序列,我必須使用哪些因素才能將腳本應用到腳本中無論使用何種解釋器,都可以生成並驗證一個密鑰。 – RobertPitt 2010-09-10 20:55:57
我編輯了我的答案,以顯示我在粘貼過程中所做的一些示例。 – Bot 2010-09-10 21:27:13
如果您想要集中創建隨機序列號,只需從數字和字母數組中隨機獲取就足夠了。使用mt_rand(0, count($poolArray))
每次獲得一個新的索引,只需將該字符添加到您的序列號中,直到您有12個字符。
從這樣一個龐大的游泳池(26個字母+10位數)中隨機生成它們幾乎可以確保您沒有重複,但您可以隨時在存儲新遊戲之前檢查現有遊戲。
如果您有36個可能的字符,並且您從中隨機選取12個字符串來製作您的連續字符串,即36 * 36 * 36 * ... * 36 = 36^12 = 4738381338321616896可能的字符串。
$pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$countPool = count($pool) ;
$totalChars = 12 ;
$serial = '' ;
for ($i = 0 ; $i < $totalChars ; $i++) {
$currIndex = mt_rand(0, $countPool) ;
$currChar = $pool[$currIndex] ;
$serial .= $currChar ;
}
分配他們與您的代碼或讓您的程序檢查有效的序列是另一個問題。
已經很好回答的問題的答案很晚,但這是我們的解決方案。它會根據有效的IPv4,Userid(或任何有意義的整數)或文本字符串生成可配置大小/長度和可選後綴的密鑰。它還避免了標準結果中的模糊字符(i,1,l,0,o,O)。
我們在許可證中附加了Userid,然後可以將該部分轉換回base10整數,並檢查它是否對使用許可證的用戶帳戶有效。
$license = generate_license();
// YF6G2-HJQEZ-8JZKY-8C8ZN
$license = generate_license(123456);
// ZJK82N-8GA5AR-ZSPQVX-2N9C
$license = generate_license($_SERVER['REMOTE_ADDR']);
// M9H7FP-996BNB-77Y9KW-ARUP4
$license = generate_license('my text suffix');
// Q98K2F-THAZWG-HJ8R56-MY-TEXT-SUFFIX
我們這樣做時創建的數據庫檢查的獨特性,但與隨機性結合使用IP /用戶ID,複製的可能性幾乎爲零。
/**
* Generate a License Key.
* Optional Suffix can be an integer or valid IPv4, either of which is converted to Base36 equivalent
* If Suffix is neither Numeric or IPv4, the string itself is appended
*
* @param string $suffix Append this to generated Key.
* @return string
*/
function generate_license($suffix = null) {
// Default tokens contain no "ambiguous" characters: 1,i,0,o
if(isset($suffix)){
// Fewer segments if appending suffix
$num_segments = 3;
$segment_chars = 6;
}else{
$num_segments = 4;
$segment_chars = 5;
}
$tokens = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$license_string = '';
// Build Default License String
for ($i = 0; $i < $num_segments; $i++) {
$segment = '';
for ($j = 0; $j < $segment_chars; $j++) {
$segment .= $tokens[rand(0, strlen($tokens)-1)];
}
$license_string .= $segment;
if ($i < ($num_segments - 1)) {
$license_string .= '-';
}
}
// If provided, convert Suffix
if(isset($suffix)){
if(is_numeric($suffix)) { // Userid provided
$license_string .= '-'.strtoupper(base_convert($suffix,10,36));
}else{
$long = sprintf("%u\n", ip2long($suffix),true);
if($suffix === long2ip($long)) {
$license_string .= '-'.strtoupper(base_convert($long,10,36));
}else{
$license_string .= '-'.strtoupper(str_ireplace(' ','-',$suffix));
}
}
}
return $license_string;
}
我的解決方案
implode('-', str_split(substr(strtoupper(md5(time() . rand(1000, 9999))), 0, 20), 4));
這非常優雅! – 2017-11-20 05:32:03
好!鑑於串行你可以解碼回日期? – 2018-01-01 17:28:09
周圍信息很好 – Fanis 2010-09-10 21:03:56
完美,只是我一直在尋找的信息類型:),非常棒的閱讀。 +1 – RobertPitt 2010-09-10 21:12:59
: - 這正是我所說的。 – Bot 2010-09-11 16:50:47