共享軟體中註冊部分的簡單實現(轉)
共享軟體中註冊部分的簡單實現(轉)[@more@]目前,很多共享軟體中使用註冊碼來實現對軟體的保護。所謂註冊碼,就是一組與使用者的某些特定資訊(如使用者名稱稱、計算機硬體等等)相關的字串。由於註冊碼傳輸起來比較簡單,同時容易驗證(相對於磁碟、光碟指紋等),因此現在註冊碼的應用越來越廣泛,甚至一些商業軟體,如Windows XP也使用了類似的機制(Microsoft稱為Windows Product
Activation)。
談起註冊碼,就不能不提註冊器。註冊器是用來產生註冊碼的程式,其計算邏輯通常與受保護的應用程式一致。透過與受保護應用程式相同,或預先約定的計算邏輯得到的註冊號,將決定受保護應用程式的行為,如顯示“軟體未註冊”、禁用某些功能,或在“關於”對話方塊中顯示註冊者的姓名,等等。
其中,終端使用者透過某種方式提交其註冊資訊,例如他(或他所在的組織)的名字,甚至極端一些,提供某些可以確定某人身份的資訊,如Pentium III CPU的CPU ID,硬碟的序列號,網路卡的MAC地址等等。然後,註冊伺服器,或呼叫中心的服務人員根據使用者提供的資訊,計算一個註冊號,並告訴終端使用者。
通常,由於人工操作可能造成差錯,我們希望註冊過程由計算機自動實現。不過這就帶來了一個問題:使用者憑什麼相信我們的程式並不會洩漏他的個人隱私呢?針對這一問題,目前流行的做法是提供若干選項,其中包括電話註冊,網路註冊,以及平信註冊等等,並把程式提交的內容告知使用者。
此外,某些與使用者的電腦相關的資訊,如配置等等,不宜使用明文傳送。這一方面是由於使用者可能不願意將這些資訊透露給我們,另一方面是以明文傳送資訊可能會導致第三方(如 cracker)截獲資訊。目前比較流行的方法是把那些我們並不需要,但卻決定使用者身份的資訊用某種雜湊演算法進行編碼然後再傳送。當然,在傳送過程中我們可以使用SSL加密,或者其他一些方法來保證安全,由於與本文的主要內容關係不大,在此不贅述,讀者可參考相關書籍。
需要保密的使用者資訊→ 雜湊演算法 → 安全傳輸(如SSL) →伺服器
就筆者個人的經驗,計算註冊碼和驗證註冊碼使用不同的演算法,可以在一定程度上提高註冊過程的安全性。當然,任何安全措施都不可能保證不被解密,“世界上沒有打不開的鎖”,解密只是一個時間問題,在構造註冊碼演算法的時候,只要讓解密代價大於軟體價值即可,不必做得太複雜。
作為使用者而言,無論是用什麼註冊方式,他都不希望過於複雜。透過計算機直接註冊的方式無疑是最方便的,但很多使用者可能不願意這樣做。作為使用者來說,透過電話註冊這種方式,說出自己的註冊ID(通常包括了產品ID、使用者的名字等資訊),以及輸入註冊碼應該是各種註冊方式中最麻煩的一種。
註冊ID和註冊碼應該具有以下特點:
(1)便於辨認、輸入。註冊碼不是密碼,沒有必要是用大量的特殊符號、大小寫組合。因此,註冊碼和註冊ID中不應該包含不同大小寫的字母,以及容易混淆的數字(1-I,0-O,2-Z)。
(2)具有查錯能力。統計證明,輸入註冊碼時,錯序(如把1234輸入成1243)、擊鍵錯誤是最常見的錯誤。比較常用的方法是把註冊碼分成若干節,每節包括一個校驗碼,這樣註冊碼就具有查錯能力了。
為了體現上面的要求,我構造了一個這樣的演算法:
(1)計算輸入的使用者名稱,並按照下面的規則計算和:
設結果為a,預置為0
按順序取使用者名稱字串的每一個字元的ASCII值,乘上位號,累加到a上。
例如:
J a s o n L i
1 2 3 4 5 6 7 8
這樣,a=(char)’J’+((char)’a’)*2+((char)’s’)*3+...
(2)將a、a²按照一定規則變換之後成為註冊字串。
實現程式如下:
// reg.cpp : Demo program for Keygen
// By Jason Li, 2001. Written for FrontFree techonology network
#include <string>
#include <iostream>
using namespace std;
typedef int BOOL;
const BOOL TRUE=(1==1);
const BOOL FALSE=!TRUE;
// Define the magic string
const string sMagic="L5WXTUYJH7VMB4GA8SFKQN9E36RPDC";
string GetRegstr(string &sName){
string sResult="FFTN-";
long lSum=0;
long lSum1;
long lChksum;
register unsigned int i;
// Calculate the registration string
for(i=0;i<sName.length();i++){
lSum += sName.at(i) * (i+1);
}
// The checksum prevents accident input
lChksum=sMagic.at(lSum%30);
sResult+=sMagic.at(lSum%30);
lSum1=lSum;
for(i=0;i<4;i++){
sResult+=(char)((lSum%10)+’0’);
lChksum+=((lSum%10)+’0’);
lSum/=10;
}
sResult+=(sMagic.at(lChksum%30));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/3;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=7;
}
sResult+=(sMagic.at(lChksum%36));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/5;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=11;
}
sResult+=(sMagic.at(lChksum%36));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/7;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=17;
}
sResult+=(sMagic.at(lChksum%30));
return sResult;
}
int main(void){
string sName;
string sRegstr;
// Output the prompt for user
cout << "Registration Code Generator DEMO program version 1.00" << endl;
cout << "By Jason Li, 2001. For test purpose only." << endl;
cout << endl;
// Loop until the user name is legal to the algorithm
do{
// Get the user name
cout << "Enter the user’s name (5 chars min), followed by comma(,): ";
getline(cin, sName, ’,’);
}while(sName.length()<=5);
cout<<"User "<<sName;
sRegstr=GetRegstr(sName);
cout<<" has the registration string of "<<sRegstr;
cout<<endl;
return 0;
}
程式按ANSI C++標準編寫,在Visual C++ 6和GNU C++中執行通
Activation)。
談起註冊碼,就不能不提註冊器。註冊器是用來產生註冊碼的程式,其計算邏輯通常與受保護的應用程式一致。透過與受保護應用程式相同,或預先約定的計算邏輯得到的註冊號,將決定受保護應用程式的行為,如顯示“軟體未註冊”、禁用某些功能,或在“關於”對話方塊中顯示註冊者的姓名,等等。
其中,終端使用者透過某種方式提交其註冊資訊,例如他(或他所在的組織)的名字,甚至極端一些,提供某些可以確定某人身份的資訊,如Pentium III CPU的CPU ID,硬碟的序列號,網路卡的MAC地址等等。然後,註冊伺服器,或呼叫中心的服務人員根據使用者提供的資訊,計算一個註冊號,並告訴終端使用者。
通常,由於人工操作可能造成差錯,我們希望註冊過程由計算機自動實現。不過這就帶來了一個問題:使用者憑什麼相信我們的程式並不會洩漏他的個人隱私呢?針對這一問題,目前流行的做法是提供若干選項,其中包括電話註冊,網路註冊,以及平信註冊等等,並把程式提交的內容告知使用者。
此外,某些與使用者的電腦相關的資訊,如配置等等,不宜使用明文傳送。這一方面是由於使用者可能不願意將這些資訊透露給我們,另一方面是以明文傳送資訊可能會導致第三方(如 cracker)截獲資訊。目前比較流行的方法是把那些我們並不需要,但卻決定使用者身份的資訊用某種雜湊演算法進行編碼然後再傳送。當然,在傳送過程中我們可以使用SSL加密,或者其他一些方法來保證安全,由於與本文的主要內容關係不大,在此不贅述,讀者可參考相關書籍。
需要保密的使用者資訊→ 雜湊演算法 → 安全傳輸(如SSL) →伺服器
就筆者個人的經驗,計算註冊碼和驗證註冊碼使用不同的演算法,可以在一定程度上提高註冊過程的安全性。當然,任何安全措施都不可能保證不被解密,“世界上沒有打不開的鎖”,解密只是一個時間問題,在構造註冊碼演算法的時候,只要讓解密代價大於軟體價值即可,不必做得太複雜。
作為使用者而言,無論是用什麼註冊方式,他都不希望過於複雜。透過計算機直接註冊的方式無疑是最方便的,但很多使用者可能不願意這樣做。作為使用者來說,透過電話註冊這種方式,說出自己的註冊ID(通常包括了產品ID、使用者的名字等資訊),以及輸入註冊碼應該是各種註冊方式中最麻煩的一種。
註冊ID和註冊碼應該具有以下特點:
(1)便於辨認、輸入。註冊碼不是密碼,沒有必要是用大量的特殊符號、大小寫組合。因此,註冊碼和註冊ID中不應該包含不同大小寫的字母,以及容易混淆的數字(1-I,0-O,2-Z)。
(2)具有查錯能力。統計證明,輸入註冊碼時,錯序(如把1234輸入成1243)、擊鍵錯誤是最常見的錯誤。比較常用的方法是把註冊碼分成若干節,每節包括一個校驗碼,這樣註冊碼就具有查錯能力了。
為了體現上面的要求,我構造了一個這樣的演算法:
(1)計算輸入的使用者名稱,並按照下面的規則計算和:
設結果為a,預置為0
按順序取使用者名稱字串的每一個字元的ASCII值,乘上位號,累加到a上。
例如:
J a s o n L i
1 2 3 4 5 6 7 8
這樣,a=(char)’J’+((char)’a’)*2+((char)’s’)*3+...
(2)將a、a²按照一定規則變換之後成為註冊字串。
實現程式如下:
// reg.cpp : Demo program for Keygen
// By Jason Li, 2001. Written for FrontFree techonology network
#include <string>
#include <iostream>
using namespace std;
typedef int BOOL;
const BOOL TRUE=(1==1);
const BOOL FALSE=!TRUE;
// Define the magic string
const string sMagic="L5WXTUYJH7VMB4GA8SFKQN9E36RPDC";
string GetRegstr(string &sName){
string sResult="FFTN-";
long lSum=0;
long lSum1;
long lChksum;
register unsigned int i;
// Calculate the registration string
for(i=0;i<sName.length();i++){
lSum += sName.at(i) * (i+1);
}
// The checksum prevents accident input
lChksum=sMagic.at(lSum%30);
sResult+=sMagic.at(lSum%30);
lSum1=lSum;
for(i=0;i<4;i++){
sResult+=(char)((lSum%10)+’0’);
lChksum+=((lSum%10)+’0’);
lSum/=10;
}
sResult+=(sMagic.at(lChksum%30));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/3;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=7;
}
sResult+=(sMagic.at(lChksum%36));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/5;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=11;
}
sResult+=(sMagic.at(lChksum%36));
sResult+="-";
lChksum=0;
lSum=lSum1*lSum1/7;
for(i=0;i<5;i++){
sResult+=sMagic.at(lSum%30);
lChksum+=sMagic.at(lSum%30)*((i%2)+1); // Sum even bytes twice
lSum/=17;
}
sResult+=(sMagic.at(lChksum%30));
return sResult;
}
int main(void){
string sName;
string sRegstr;
// Output the prompt for user
cout << "Registration Code Generator DEMO program version 1.00" << endl;
cout << "By Jason Li, 2001. For test purpose only." << endl;
cout << endl;
// Loop until the user name is legal to the algorithm
do{
// Get the user name
cout << "Enter the user’s name (5 chars min), followed by comma(,): ";
getline(cin, sName, ’,’);
}while(sName.length()<=5);
cout<<"User "<<sName;
sRegstr=GetRegstr(sName);
cout<<" has the registration string of "<<sRegstr;
cout<<endl;
return 0;
}
程式按ANSI C++標準編寫,在Visual C++ 6和GNU C++中執行通
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-957679/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用硬體資訊實現共享軟體的安全註冊 (4千字)
- 小弟為共享軟體作者製作的管理軟體註冊的動態連結庫 (轉)
- node+express+mongDB實現簡單登入註冊Express
- mvc架構的簡單實踐----使用者註冊的實現MVC架構
- 發現一個實現簡單地圖示註的視覺化軟體地圖視覺化
- 在 Golang 中實現一個簡單的Http中介軟體GolangHTTP
- HTML基礎實現簡單的註冊和登入頁面HTML
- 簡單登入註冊實現(Java物件導向複習)Java物件
- 直播軟體app開發,HTML和CSS分別實現註冊頁面表單APPHTMLCSS
- Mac電腦簡單實用的防火牆軟體:Radio Silence 註冊碼中文版Mac防火牆
- 從零開始實現簡單 RPC 框架 4:註冊中心RPC框架
- C#實現無法破解的軟體註冊碼演算法C#演算法
- Laravel6 簡單使用 API 註冊訪問實現(適合菜鳥)LaravelAPI
- 簡單實現登陸註冊gui介面以及打包成exe檔案GUI
- 軟體開發中的矛盾——一個簡單的例子 (轉)
- html+JS+php實現簡單的註冊使用者名稱驗證HTMLJSPHP
- Express中介軟體body-parser簡單實現Express
- 實現類的註冊方法
- 巨集遠簡訊群發軟體(個人版)註冊分析
- WIN下動態註冊碼實現方法 (轉)
- Getway實現nacos註冊及服務轉發
- 給自己的軟體製作註冊碼
- 軟體介面中選單的美化 (轉)
- Java Web中的入侵檢測及簡單實現(轉)JavaWeb
- C#基於RSA加密演算法實現軟體註冊實戰演練C#加密演算法
- Python + Tkinter簡單實現註冊登入(連線本地MySQL資料庫)PythonMySql資料庫
- jQuery實現的表單註冊驗證程式碼例項jQuery
- 簡單實現Windows和Linux檔案共享WindowsLinux
- 使用 python 實現簡單的共享鎖和排他鎖Python
- 超級簡單的實現window共享Linux檔案Linux
- 對軟體行業的簡單認識 (轉)行業
- BAPI的簡單實現步驟(轉)API
- TP5 實現簡訊驗證碼註冊功能
- 中文內碼轉換巨匠1.2【VB簡單】註冊演算法演算法
- 成品直播原始碼推薦,登入和註冊兩個頁面的簡單實現原始碼
- NodeJs 建立一個簡單的登陸註冊NodeJS
- 共享軟體幽默廣告獎 (轉)
- 共享軟體產業化(上) (轉)產業