#!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP #!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP

3D
3D Photo Gallery (Part 1)
3D Photo Gallery (Part 2)

Audio
Poor Man's MIDI
Make A Metronome
iPod Tricks (Part 1)
iPod Tricks (Part 2)
iPod Tricks (Part 3)
Laugh Track Machine
Audio Player with Reverb
Shepard Melody
RB Phone Home
Build a Drum Machine

Custom Controls and Windows
Double Click Listbox
Draggable Metal Window
Double Click Canvas
Custom Buttons
Custom Buttons Part II
iTunes-style Listboxes
Custom Controls


General RB
Scrolling Windows
Using Mesage Dialogs
Case-Sensitive Word Finder
Introduction to Stacks
Wiggle Window
JPEG in PDF
Listbox Checkboxes
Background Applications
Listbox Auto-Find
Virtual Volumes
Time Tracker
Software Distribution (Part 1)
Software Distribution (Part 2)
Software Distribution (Part 3)
Software Distribution (Part 4)
Exceptions
Tips and Tricks
Text Clippings Made Easy

Graphics
Drawing a Simple Gradient
The SpriteSurface: Space Game
Image Spinner
Cropping Graphics (Part 1)
Cropping Graphics (Part 2)
Cropping Graphics (Part 3)
Cropping Graphics (Part 4)
Shimmer Graphics
Lissajous Figures
Simple Screen Capture
Vector Graphics
Kaleidoscope Images
Stegonography
Spirals!
Image Table
RB Magnifying Lens
Screen Capture
Color Picker Tutorial

Hacks
Ghost Grab
Speedy Mouse Extension
iTunes Plugins
iTunes Skinner

Mac OS X
Global Hot Key Event (Carbon Events)
Login Welcomer (Carbon Events)
Add/Remove Buttons
Resizable Sheets
Mac OS X Preferences Window
Using Sheets in REALbasic
Build a Bundle (Part 1)
Build a Bundle (Part 2)
Dock Your Passwords
Mac OS X Debugging
REALbasic Mac OS X Icon Tutorial
Animate Your Dock
RB and the Command Line

Menus
Window Menu
Templates Menu
Listbox Menu

Novelty
Guessing Game
Calendar Trivia
Tile Mixer
Zip Code Finder
Happy Valentine's Day
Merlin Simulator (Part 1)
Merlin Simulator (Part 2)
Merlin Simulator (Part 3)
Buzzword Machine
AppleSoft BASIC

Printing
Print to PDF

Registration
Registration Code Validation
Network Registration Codes

Resources
Picture Extractor (Part 1)
Picture Extractor (Part 2)

Serial
Caller ID (Part 1)
Caller ID (Part 2)
Caller ID (Part 3)

Speech
Speech Recognition

Socket Communication
Easy Peer-to-Peer File Sharing
MacPAD Version Checking
Display Web Image In Canvas
HTML IMG Tags
Version Tracking
Even Smarter Instant Messaging
Web Tiler
JavaScript and REALbasic
Stock Ticker (Part I)
Stock Ticker (Part 2)
AIM Mate

XML Manipulation
Simple XML Introduction

Video
Big Brother Video Capture

Note: All articles without a byline were written by Erick Tejkowski. When cleaning the site I removed them because the code differed from page to page, and I have yet to put them back in.

resexc2.gif (20k)




REALbasic for Dummies
by Erick Tejkowski

$19.99 @ Amazon





Files are in Stuffit 6.5 or earlier, or ZIP format.
Download Stuffit Expander

Tell us about a bad link.

Registration Code Validation by Seth Willits
09-24-03




Registration schemes are always "beyond" new programmers. If you're on the REALbasic mailing list, you'll see a message about once every other month on the topic, and the main reason is, new programmers, or more correctly, new registration scheme coders, don't know what a registration scheme is and are afraid of doing it wrong. (And you can believe me because I was one of them.) The strange thing is, there is no way to do it wrong.

What are registration numbers and generators?
A registration number is simply a unique string of characters which can be identified as being "valid" or "invalid," and all that a registration code generator is, is an algorithm to create valid registration numbers. So if you had an algorithm that generated numbers from 10000 - 29999 and all your application did to determine if a number was valid or not was check to see that the first character was a 1 or a 2, then you've got yourself a registration code generator, although not a very secure one since the chance of guessing a code is really high. Note what I just said, *the chance*. All that is required of a good RCG is for it to make very unique values, or in other words, a string of characters which must meet a demanding set of requirements.

An Example
For example, a simple validation routine could require that ASCII value of the string's first character multiplied by the ASCII value of the second character, divided by the ASCII value of the third, added to the values of the next five characters (which can only be numbers) must be between 12572 and 23639. Valid numbers for this would include:

ABC12345 and 10A20763, but QEP10310 would not work because Asc("Q") * Asc("E") / Asc("P") + 10310 is equal to 10379.86 which does not meet our requirement. Also note that 10A2076B would not work because the last character is a letter and not a digit.

So you see, all that a registration code generator must do, is produce numbers which meet a strict set of rules created by the registration code validator.

This Tutorial's Project
The project for this tutorial will actually be a modified REALbasic version of a project I found for Cocoa at CocoaDevCentral which demonstrates how to create a registration code that requires the user's name for validation (which I find to be pretty neat). The only thing I didn't like about their example was that they didn't explain how to validate their registration numbers which is the most important step, so we'll definitely cover that here.

Ok, well start by creating a new project and make an interface that looks like this:

Ok, now the format of the registration numbers we're going to be making will have two letters, 3 numbers, a hyphen, and then two sets of four numbers also separated by a hyphen:

SF100-4944-9222

The first character will be what kind of license it is. S is for single, M is for multi, and G is for group. "F" is just a single character for you to know which application the registration code belongs to, and the next three characters are the version number of the application and can be used to test different versions of the registration algorithm, but we won't go into that so just call it filler space, and then the next 8 numbers are the real meat of the code. These 8 bytes will be the realy "generated" part of the number, and the bytes we use to do validation with.

Code Generation
Ok, so lets create the code for the "Generate" button. The first thing we're going to do is declare some variables for us to use and then set them up. We're going to use a memory block named code, two integers num1 and num2, and then a string named "name" which will hold the value that you enter for their name. (Remember, right now we're building a code generator for you to use, later we'll build the generator you will put into the actual application.) Assign the value of the name field to the "name" variable and create a memory block with 15 bytes of space for the "code" variable.



Next, assign default values to each of the 15 bytes in the memory block.



(Now we reall don't need to do this, but it really helps to clarify what is where as far as which character is in which byte position. All that we really need to do is assign a character to byte 1 to represent which application it is, the version number to bytes 2-4, and hypens in bytes 5 and 10. All of the other bytes are just overwritten.)

Next, assign the value of the first byte to be a character representing which of the three license types the user bought (S for single, M for mutli, and G for group).




(Now from here on, the numbers and characters you use are ultimately up to you; Just keep in mind that this is one example of how you might create a registration code generator, it's not the "right way.")

Next we're going to assign the 8th, 4th, 3rd, and 1st characters of the user's name to the 6th, 7th, 8th, and 9th bytes of the "code" memoryblock respectively. After that, we're going to do some random math with the value of these four bytes and come up with a number. Using "Seth Willits" as an example, the number generated by the code below is 4076.




Then we're going to take that number and place it in those 4 bytes (6, 7, 8, and 9).


      code.StringValue(6, 4) = Format(num1, "0000")

Then for our next four bytes, or the last for characters of our registration code, we're going to a very similar process but change the math just a little bit and use different characters of the name to start with.




Now after assigning those last four characters, you're done generating the number for that name, so go ahead and put that number into the code field:

      CodeField.Text = code.StringValue(0, code.size)

Code Validation
"So how to we put this registration code to the test?" QED. (Quite easily done. I had a math teacher who would write that after problems that took up two chalkboards.) All we need to do, is have the user enter their name, create the registration code for that name, and compare it to the registration code they entered. As you probably noticed, the registration code generator is actually part of the registration code validator. It makes sense, doesn't it? How else could you test the number if you don't know what it's supposed to be?

Ok, well anyway, go ahead and implement this interface:

Next, copy the code which creates the registration code into the validate button, delete the lines that test which radio button is selected, and instead of the last line (CodeField.Text = code.StringValue(0, code.size)) write:

     if Mid(CodeField.Text, 2) = code.StringValue(1, code.size - 1) then
         MsgBox "Valid"
     else
MsgBox "Invalid"
     end if

So the code you end up with is:




Go ahead and try it with different names and test validating with the correct codes and wrong codes. Pretty cool, huh?

As you may have noticed, this example is not 100% "perfect" but works 100% of the time. For example, names with fewer than 8 characters will generate semi ununique numbers. In reality, even with this possibility, the method still works and works well. I've even implemented a version of this same type of algorithm in my own applications because it's simple and effective. With registration validation, anything goes. The really tricky part is trying to keep crackers or warez groups from redistributing your serial numbers!






Please support ResExcellence by Visiting our Sponsors. One click makes a difference.


Download REALbasic and create your own software!

#!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP #!/usr/bin/perl -w # # Copyright 2000 by Michael Coyle # Released under GPL. # # Call it with: # [an error occurred while processing this directive] # # Get the file name from the browser... $file_name = $ENV{'QUERY_STRING'}; # Open the file... open (EP, $file_name); # Print to the browser... print "Content-Type: text/html \n\n"; # Load the file and keep spitting it out to the browser... while () { chomp; print "$_ "; } # Close the file and go home... close EP