• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 共享軟件中注冊部分的簡單實現

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    目前,很多共享軟件中使用注冊碼來實現對軟件的保護。所謂注冊碼,就是一組與用戶的某些特定信息(如用戶名稱、計算機硬件等等)相關的字符串。由于注冊碼傳輸起來比較簡單,同時容易驗證(相對于磁盤、光盤指紋等),因此現在注冊碼的應用越來越廣泛,甚至

    目前,很多共享軟件中使用注冊碼來實現對軟件的保護。所謂注冊碼,就是一組與用戶的某些特定信息(如用戶名稱、計算機硬件等等)相關的字符串。由于注冊碼傳輸起來比較簡單,同時容易驗證(相對于磁盤、光盤指紋等),因此現在注冊碼的應用越來越廣泛,甚至一些商業軟件,如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++中運行通

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>