Some time ago, I wrote a few functions to provide a software "key" to help protect my software.
Looks like there was a small bug so I am posting it again.
The code above the "//////////////////////////////" is just to show how to use my functions, the stuff below are the functions.
I hope it can help others ... Enjoy
- Code: Select all Expand view
- /* In the examples below we will use the following walues for the parameters:
nKey = 123
nLicense = 5
nSerial = 1221404635 //from my system
cKey = 403-57723-2677-6150 //from my system
*/
#include "FiveWin.ch"
Static cStored, cKey, nSerial, oKeyGen
Function Main()
Local oWnd, oBtn
Define Window oWnd
@ 2,1 Say "NSerialHD on this system = "+STR( nSerialHD() )
@ 3,1 Say "cKey on this system = "+ MakeKey(123,5)
@ 5,1 BUTTON oBtn PROMPT "Test MakeKey( nKey, nLicense )" SIZE 300,25 Action TMakeKey1()
@ 7,1 BUTTON oBtn PROMPT "Test MakeKey()" SIZE 300,25 Action TMakeKey2()
@ 9,1 BUTTON oBtn PROMPT "Test VerifyKey( nKey, nLicense, cKey )" SIZE 300,25 Action TVerifyKey()
@ 11,1 BUTTON oBtn PROMPT "Test GetLicense( nKey, cStored )" SIZE 300,25 Action TGetLicense()
Activate Window oWnd
Return Nil
Function TMakeKey1()
/* Test Makekey() and provide nKey and nLicense
This is used on the computer you are making a key for.
MakeKey( nKey, nLicense ) will return the cKey for the computer it is run on
nKey is your secret key
nLicense is the number of licenses you are giving to end user (it is only a number
you must do the code to limit your app)
*/
//below we will use 123 as our secret key and give 5 licenses
//what is displayed in the message box is the users software key
Msginfo( MakeKey( 123 , 5 ) )
Return Nil
Function TMakeKey2()
/* Test Makekey() without and parameters
This is used on any computer.
It will ask for nKey (your secret key), nSerial (nSerialHD() from the users computer) and
nLicense (number of licenses you are giving to end user (it is only a number you must do
the code to limit your app)
MakeKey() will return the cKey
*/
MakeKey()
Return Nil
Function TVerifyKey()
/* VerifyKey( nKey,nLicense, cKey) returns a logical T or F
nKey is your secret key
nLicense is the number of licenses you are giving to end user (it is only a number
you must do the code to limit your app)
cKey is the users software key (See MakeKey() )
*/
If VerifyKey( 123, 5, "403-57723-2677-6150")
MsgInfo( "Key is good" )
Else
MsgInfo( "Key is bad" )
Endif
Return Nil
Function TGetLicense()
/* GetLicense( nKey, cStored )
nKey is your secret key
cStored is the users software key (same as cKey...see MakeKey() )
Returns nLicense
*/
MsgInfo( GetLicense( 123, "403-57723-2677-6150" ) )
Return Nil
///////////////////////////////////////////////////////////////////////////////////////
Function MakeKey(nKey,nLicense,lGetSecretKey, nSerial2)
Local nTotal1:=0, nTotal2:=1,nTotal3:=0
Local cDigit, i, lVisable:=.f.
Local cHash1:=0, cHash2:=0, cHash3:=0, cHash4:=0
Local cKey:=""
Local nCount:=0
Local nSerial:=nSerialHD(), oClp
IF Empty(lGetSecretKey)
lGetSecretKey := .f.
ELSE
nSerial := nSerial2
ENDIF
if Empty(nLicense)
nLicense:=1
endif
if Empty(nKey)
lVisable:=.t.
nKey:=1
nSerial:=0
MsgGet("Key Generator","Enter Key: ",@nKey)
MsgGet("Key Generator","Enter Serial Number: ",@nSerial)
MsgGet("Key Generator","Number of Licenses: ",@nLicense)
endif
nCount:=len(alltrim(str(nSerial)))
For i = 1 to nCount+1
cDigit := SubStr( alltrim(str(nSerial)) ,i,1)
nTotal1:=nTotal1+val(cDigit)
if val(cDigit)<>0
nTotal2:=nTotal2*val(cDigit)
endif
nTotal3:=nTotal3+(val(cDigit)*nCount)
Next
cHash1:=alltrim(str(nTotal1*nCount+nKey))
cHash2:=alltrim(str(nTotal2*nCount+nKey))
cHash3:=alltrim(str(nTotal3*nCount-nKey))
cHash4:=alltrim(str(nLicense*nCount*nKey))
cKey:= cHash1+"-"+cHash2+"-"+cHash3+"-"+cHash4
IF lVisable
MsgInfo("Serial Number: "+str(nSerial)+CRLF+"Key: "+cKey,"Key Generator")
Define Window oKeyGen FROM 0,0 to 0,0
Define CLIPBOARD oClp of oKeyGen
Activate CLIPBOARD oClp
oClp:SetText("Serial Number: "+str(nSerial)+CRLF+"Key: "+cKey+CRLF+"Licenses: "+str(nLicense))
MsgInfo("The KEY has been copied to the clipboard")
Activate Window oKeyGen on init oKeyGen:End()
Endif
Return cKey
Function VerifyKey(nKey,nLicense,cStored)
If Empty(nKey) .or. Empty(cStored)
MsgInfo("A value is missing for VerifyKey()","KeyGen Error")
Return .f.
endif
If MakeKey(nKey,GetLicense(nKey,cStored)) = cStored
Return .t.
else
Return .f.
endif
return nil
Function GetLicense(nKey,cStored)
Local nLicense, i, j:=0, cHash4:="", nCount
If Empty(nKey) .or. Empty(cStored)
MsgInfo("A value is missing for GetLicense()","KeyGen Error")
Return Nil
endif
nCount:=Len(alltrim(cStored))
for i = 1 to nCount
if substr(cStored,i,1)="-"
j=j+1
endif
if j=3
if substr(cStored,i,1)<>"-"
cHash4:=cHash4+substr(cStored,i,1)
endif
endif
next
nLicense:=val(cHash4)/nkey/ ( len( alltrim( STR( nSerialHD() ))))
return nLicense
Function GetSecretKey( nSerial, cKey )
Local cSecret
if empty(nSerial)
MsgInfo("You MUST supply a Hard Drive Serial Number","ERROR")
Quit
ENDIF
if empty(cKey)
MsgInfo("You MUST supply a Key [ made by MakeKey() ]","ERROR")
Quit
ENDIF
DEFINE WINDOW oKeyGen FROM 0,0 to 5,35 TITLE "Key Generator"
ACTIVATE WINDOW oKeyGen on INIT cSecret:=DoSecret( nSerial, cKey )
Return cSecret
Function DoSecret( nSerial, cKey )
Local nSecret := 0, lSearching := .t., nCount, i:=0, j
Local cGetKey, cTempKey:="", cTemp:=""
Local cHash1:="", cHash2:="", cHash3:="", cHash4:=""
Local cGetHash1:="", cGetHash2:="", cGetHash3:="", cGetHash4:=""
Local oSay
IF ! MsgYesNo("This may take a LONG TIME to run, Continue?","Find Secret Key")
Quit
ENDIF
FOR j = 1 to len(trim(cKey))
i++
cTemp := SUBSTR( cKey, i, 1 )
cTempKey = cTempKey + cTemp
IF cTemp = "-"
if EMPTY( cHash1 )
cHash1:=Left( cTempKey,len( trim( cTempKey ))-1 )
cTempKey:=""
loop
endif
if EMPTY( cHash2 )
cHash2:=Left( cTempKey,len( trim( cTempKey ))-1 )
cTempKey:=""
loop
endif
if EMPTY( cHash3 )
cHash3:=Left( cTempKey,len( trim( cTempKey ))-1 )
cTempKey:=""
loop
endif
ENDIF
NEXT
lSearching := .t.
DO WHILE lSearching
i++
@ 1,1 SAY "Working..."+STR(i) of oKeyGen COLOR "R+/W"
SysWait()
cGetKey := MakeKey( i, 5, .t., nSerial )
cGetHash1:=left(cGetKey,len(cHash1))
cGetHash2:=substr(cGetKey,len(alltrim(cHash1))+2,len(alltrim(cHash2)))
cGetHash3:=substr(cGetKey,len(alltrim(cHash1))+len(alltrim(cHash2))+3,len(alltrim(cHash3)))
if cHash1=cGetHash1 .and. cHash2=cGetHash2 .and. cHash3=cGetHash3
@ 1,1 SAY "Done....................." of oKeyGen COLOR "R/w"
SysWait()
MsgInfo("You Secret Key is: "+STR(i),"Secret Key Finder")
oKeyGen:End()
lSearching := .f.
endif
ENDDO
Return i