(c) 2001 Visual Basic Programmer's Journal
Fawcette Technical Publications

Issue: July VBPJ
Section: COMponent Builder
Author: Monte Hansen

VB6	Compute Checksums
Listing 1	The license key has embedded product information, caller-defined license counters, and an expiration date. It's also bound to the customer's name.

' convert each segment value to a hex string
KeySegs(iProdCode) = HexWORD(ProductCode)
KeySegs(iExpire) = HexWORD(DateDiff ("d", _
	DateValue(#1/1/1970#), DateValue(ExpireDate)))
KeySegs(iUserData) = HexWORD(UserData)

' Compute CRC against pertinent info.
KeySegs(iCRC) = HexWORD(CRC(UCase$(Licensee & _
	KeySegs(iProdCode) & KeySegs(iExpire) & _
	KeySegs (iUserData) & PrivateKey)))

' Perform bit swaps
For i = 0 To m_nSwaps - 1
	SwapBit m_Bits(i), KeySegs
Next i

' Calculate the CRC used to perform
' simple user input validation.
KeySegs(iCRC2) = HexWORD(CRC(UCase$(Licensee & _
	KeySegs(iProdCode) & KeySegs(iExpire) & _
	KeySegs (iUserData) & KeySegs(iCRC))))

' Return the key to the caller
CreateKey = UCase$(KeySegs(iProdCode) & "-" & _
	KeySegs(iExpire) & "-" & KeySegs(iUserData) _
	& "-" & KeySegs (iCRC) & "-" & KeySegs(iCRC2))

VB6	Use Your License Counter Segment to Store Features
Listing 2	Your license counter segment can hold all sorts of things. This technique shows how you can use it to store up to 16 available features. Use the bitwise OR when creating the license counter, and the bitwise AND when testing for the presence of a feature bit.

Const CanPrintBit = 0
Const CanSaveBit = 1
Const CanDoThatBit = 2

Dim FeatureBits As Long
Dim CanPrint As Boolean
Dim CanSave As Boolean
Dim CanDoThat As Boolean

' To build a list of feature bits 
' used to create the key:
FeatureBits = FeatureBits Or (2 ^ CanPrintBit)
FeatureBits = FeatureBits Or (2 ^ CanSaveBit)
FeatureBits = FeatureBits Or (2 ^ CanDoThatBit)

' To test for the presence of 
' feature bits:
CanPrint = _
	(FeatureBits And (2 ^ CanPrintBit)) <> 0
CanSave = _
	(FeatureBits And (2 ^ CanSaveBit)) <> 0
CanDoThat = _
	(FeatureBits And (2 ^ CanDoThatBit)) <> 0

VB6	Re-Create Only One Segment at a Time
Listing 3	A typical key validation routine re-creates a valid key, then compares it to the key entered by the user. A better approach would be to re-create only one segment at a time, comparing only CRC values.

' Get CRC used for input validation
nCrc1 = CRC(UCase$(Licensee) & _
	KeySegs(iProdCode) & KeySegs(iExpire) & _
	KeySegs(iUserData) & KeySegs(iCRC))

' Compare check digits
If (nCrc1 <> SegmentValue(KeySegs(iCRC2))) Then
	GoTo ExitLabel
End If

' The supplied product code should be the same as 
' the product code embedded in the key.
If ProductCode = SegmentValue _
	(KeySegs(iProdCode)) Then
	' One more check on the check digits before 
	' we blow away the value stored in nCrc1.
	If (SegmentValue(KeySegs(iCRC2)) = nCrc1) Then
		nCrc1 = CRC(UCase$(Licensee))
	End If
End If

nCrc2 = CRC(UCase$(KeySegs(iProdCode)), nCrc1)
nCrc3 = CRC(UCase$(KeySegs(iExpire)), nCrc2)
nCrc3 = CRC(UCase$(KeySegs(iUserData)), nCrc3)
nCrc4 = CRC(UCase$(PrivateKey), nCrc3)
