Take the 2-minute tour ×

I'm toying around with writing creating a serial code generator/validator, but I can't seem to get how to do a proper check.

Here's my generator (yea, it's nothing fancy, but this is purely for my own education, so it'll do):

# Serial generator

# Create sequences from which random.choice can choose
Sequence_A = 'ABCDEF'
Sequence_B = 'UVWQYZ'
Sequence_C = 'NOPQRS'
Sequence_D = 'MARTIN'

import random

# Generate a series of random numbers and Letters to later concatenate into a pass code
First = str(random.randint(1,5))
Second = str(random.choice(Sequence_A))
Third = str(random.randint(6,9))
Fourth = str(random.choice(Sequence_B))
Fifth = str(random.randint(0,2))
Sixth = str(random.choice(Sequence_C))
Seventh = str(random.randint(7,8))
Eighth = str(random.choice(Sequence_D))
Ninth = str(random.randint(3,5))

serial = First+Second+Third+Fourth+Fifth+Sixth+Seventh+Eighth+Ninth

print serial

I'd like to make a universal check so that my validation code will accept any key generated by this.

My intuition was to create checks such as this:

serial_check = raw_input("Please enter your serial code: ")

# create a control object for while loop
control = True

# Break up user input into list that can be analyzed individually
serial_list = list(serial_check)    

while control:
    if serial_list[0] == range(1,5):
    elif serial_list[0] != range(1,5):
        control = False

    if serial_list[1] == random.choice('ABCDEF'):
    elif serial_list[1] != random.choice('ABCDEF'):
        control = False
# and so on until the final, where, if valid, I would print that the key is valid.

if control == False:
      print "Invalid Serial Code"

I'm well aware that the second type of check won't work at all, but it's a place holder because I've got no idea how to check that.

But I thought the method for checking numbers would work, but it doesn't either.

I'm clearly new to python, and I'm stumped. Any help would be greatly appreciated!

share|improve this question
add comment

2 Answers

Regarding your python, I'm guessing that when your wrote this:

if serial_list[0] == range(1,5):

You probably meant this:

if 1 <= serial_list[0] <= 5:

And when you wrote this:


You probably meant this:

if serial_list[1] in 'ABCDEF':

There are various other problems with your code, but I'm sure you'll improve it as you learn python.

At a higher level, you seem to be trying to build something like a software activation code generator/validator. You should know that just generating a string of pseudo-random characters and later checking that each is in range is an extremely weak form of validation. If you want to prevent forgeries, I would suggest learning about HMAC (if you're validating on a secure server) or public key cryptography (if you're validating on a user's computer) and incorporating that into your design. There are libraries available for python that can handle either approach.

share|improve this answer
Thank you for your help. This isn't for anything real, I was curious as to how one would go about making something like a real serial generator and wanted to give it a shot myself and this is what I cam up with. Thanks again. –  user679400 Apr 7 '11 at 19:31
Sure. If you don't intend to ask specific question or to accept an answer, you might want to make it a wiki next time. –  ʇsәɹoɈ Apr 7 '11 at 20:30
add comment

The expression `range(1, 5)' creates a list of numbers from 1 to 4. So in your first test, you're asking whether the first character in your serial number is equal to that list:

"1" == [1, 2, 3, 4]

Probably not...

What you probably want to know is whether a digit is in the range (i.e. from 1 to 5, I assume, not 1 to 4).

Your other hurdle is that the first character of the serial is a string, not an integer, so you would want to take the int() of the first character. But that will raise an exception if it's not a digit. So you must first test to make sure it's a digit:

if serial_list[0].isdigit() and int(serial_list[0]) in range(1, 6):

Don't worry, if it's not a digit, Python won't even try to evaluate the part after and. This is called short-circuiting.

However, I would not recommend doing it this way. Instead, simply check to make sure it is at least "1" and no more than "5", like this:

if "1" <= serial_list <= "5":

You can do the same thing with each of your tests, varying only what you're checking.

Also, you don't need to convert the serial number to a list. serial_check is a string and accessing strings by index is perfectly acceptable.

And finally, there's this pattern going on in your code:

if thing == other:
elif thing != other:
   (do something)

First, because the conditions you are testing are logical opposites, you don't need elif thing != other -- you can just say else, which means "whatever wasn't matched by any if condition."

if thing == other:
   (do something)

But if you're just going to pass when the condition is met, why not just test the opposite condition to begin with? You clearly know how to write it 'cause you were putting it in the elif. Put it right in the if instead!

if thing != other:
    (do something)

Yes, each of your if statements can easily be cut in half. In the example I gave you for checking the character range, probably the easiest way to do it is using not:

if not ("1" <= serial_list <= "5"):
share|improve this answer
Thanks! Y'know I was starting to think that I should just pass the initial conditions, but I wanted to leave it in - not sure why now. –  user679400 Apr 7 '11 at 19:38
add comment

Your Answer


