Generating Unique Codes



  • I've got a situation where some instructors of courses want enrollment in those courses to be limited to people who've been given some sort of invitation code.  That's easy enough to do, but what I'm curious about is the best way to generate unique invitation codes.  Currently, I have a page where the instructor can select one of his or her courses, enter the number of invitation codes to generate, and then a stored procedure generates that number of invitation codes, using the NewID() function which returns a UUID, for that course.  I think this'll work fine, but I can see some of the instructors not liking the fact that the invitation codes are 32 characters long.

     

    How would you all go about generating unique (per course) invitation codes that are shorter than UUIDs.  Of course, the invitation codes shouldn't be easily guessable.


  • well, I know nothing about the system you are using, but I woudln't use codes like that.  I would add a list of students who are allowed to register for the class that only the professor can change. 

     

    if you can't do that then why not just do a random number generator?  



  • [quote user="tster"]

    well, I know nothing about the system you are using, but I woudln't use codes like that.  I would add a list of students who are allowed to register for the class that only the professor can change. 

     

    if you can't do that then why not just do a random number generator?  

    [/quote]

     

    That's a fine idea, but the instructors need to be able to give out invitation codes without having to wait for all the people they want to give them to to register with the site first.

     

    I thought about using some sort of random number generator, but then I'd get a situation like this:
     

           1. Generate a random number

           2. If we've already got that number in the list, start over at Step 1

           3. Add the random number to the list

           4. Repeat NumberOfCodesNeeded times

     

    where, although it's incredibly unlikely, we could get stuck on Steps 1 and 2 for eternity.



  • [quote user="UncleMidriff"][quote user="tster"]

    well, I know nothing about the system you are using, but I woudln't use codes like that.  I would add a list of students who are allowed to register for the class that only the professor can change. 

     

    if you can't do that then why not just do a random number generator?  

    [/quote]

     

    That's a fine idea, but the instructors need to be able to give out invitation codes without having to wait for all the people they want to give them to to register with the site first.

     

    I thought about using some sort of random number generator, but then I'd get a situation like this:
     

           1. Generate a random number

           2. If we've already got that number in the list, start over at Step 1

           3. Add the random number to the list

           4. Repeat NumberOfCodesNeeded times

     

    where, although it's incredibly unlikely, we could get stuck on Steps 1 and 2 for eternity.

    [/quote]
    No need to have them register before assigning them to a class.  Simpy pre-create accounts for all relevant students and make the registration process into an account activation process.  Use their school-assigned email for the activation code for the account to prevent one student from taking another student's account.  Then you will have a system based on authentication and authorization instead of shared secrets.  This is far simpler to maintain.



  • [quote user="UncleMidriff"]

    How would you all go about generating unique (per course) invitation codes that are shorter than UUIDs.  Of course, the invitation codes shouldn't be easily guessable.[/quote]

    1. Generate a random sequence of chars.

    2. Get the next auto-incremented number.

    3. Mix the two in a predefined way.

    Eg.

    1. sd3kea

    2. 000001

    3. sd3kea000001 or s000d300kea1 etc...

    This way 1. Gets you a random key that is hard to guess and 2. Gets you uniqueness.

     

     



  • [quote user="jsmith"]No need to have them register before assigning them to a class.  Simpy pre-create accounts for all relevant students and make the registration process into an account activation process.  Use their school-assigned email for the activation code for the account to prevent one student from taking another student's account.  Then you will have a system based on authentication and authorization instead of shared secrets.  This is far simpler to maintain.[/quote]

     

    Perhaps I should explain the situation a bit better.

    My organization offers courses to the public.  Any ol' John Doe can come to our site and register.  Once he has registered, he can enroll in any course he likes, so long as he meets the prerequisites for that course.  Currently, we've got a few types of prerequisites: Course B might require that you've taken and completed Course A before you can enroll in Course B, Course C might require that you've meet some requirement that is external to our system, in which case the instructor of Course C will have to manually verify that you've met that requirement before you can enroll in Course C, Course D might require you to have been given an invitation by the instructor of Course D before you can enroll in Course D, and Course E might not have any prerequisites at all.

    Once John Doe registers with our site, he can view all the information we have about him, he can manage his enrollments, he can browse our course offerings, he can make payments for any enrollments that he hasn't paid for yet, he can view certificates of completion for completed courses, etc.  Let's say he is browsing our course offerings and notices that Course D is something he'd be interested in taking.  He selects it, clicks "Enroll," and is then presented a message explaining to him that Course D is invitation only.  If he has an invitation code, he can type it in, click "Verify," and then he's on his way.  But Mr. Doe doesn't have an invitation code, because, for whatever reason, he's not the type of person that the instructor of Course D wants to teach, so Mr. Doe is out of luck.

    All the instructor has to do is generate N invitation codes for Course D and then distribute those to whoever he wants to, however he wants to.  Once a person has an invitation code, all they have to do is log in, try to enroll in Course D, and enter the code when prompted.  If they haven't yet registered, then they'll have to register before trying to enroll.  I guess the instructor could contact each person he'd allow to take the course, gather up all the information needed for registration for each person, register the ones that haven't already done so, and then mark them, out of all the people registered in the system, as being able to attend Course D, but it'd probably be easier just to email some invitation codes and let the invitees worry about registering themselves.  And regardless of which way is easier, this is how the requirements document I have for this project says to do it.

    So, there's that. :-)


     



  • Thanks for the more in depth explanation, that helps.  Here's my suggestion.

    Since you own the website that people register through, is it not possible to create a private page in a secured area for the instructors of said course?  If so, I'd dump the idea of pre-generated keys and provide the isntructors with a UI in which they type the e-mail address of the person they want to invite to the course.

     The system can, then, send out an e-mail to that person containing a link to an invitation page, where they can register for the course.  The link would contain the invitation code as a get parameter to the page.

    Finally, I'd recommend that the invitation code be a hash of the person's e-mail address (or maybe even their first name, last name, and e-mail address).  Then, the invitation page could verify that the information typed in the page matched the invitation code given, so that only the person invited would be able to enroll in the course, even if the e-mail with the invitation code was forwarded on to another person.



  • After re-reading your statement about being able to provide the code 'however the instructor wants', maybe my suggestion doesn't quite fit the requirements... 

    One other question...

    What purpose does it serve to have unique invitation codes?  Why not just make a single password that the instructor can give out to N people?  Just wondering if there's a security requirement buried here, or if it's just a way for the instructor to keep track that he/she has given out N invitations...



  • [quote user="baldheadedguy"]

    After re-reading your statement about being able to provide the code 'however the instructor wants', maybe my suggestion doesn't quite fit the requirements... 

    One other question...

    What purpose does it serve to have unique invitation codes?  Why not just make a single password that the instructor can give out to N people?  Just wondering if there's a security requirement buried here, or if it's just a way for the instructor to keep track that he/she has given out N invitations...

    [/quote]

     

    The reason for having different codes is so that Bobby, who the instructor invited to the course, can't pass along the invitation code to all of his buddies, who the instructor didn't invite to the course.  I should note that whenever an invitation code is used the system records who used it, and then that invitation code becomes useless.



  • It sounds like the invitation system is not up for debate, and I'd think that it's pretty sound. After all, it's pretty much along the lines of the various invitation-only services that pop up online every now and then.

    What you could consider is reverse-invitations. Rather than having the instructor give the student an invitation code, the student gives the instructor his system username. The instructor goes to the course administration page, clicks on 'add student', and the given account is added. Since registration is open to anyone, the students can register in advance, and it's much easier than doing it the other way around.

    Is there any point in adding users that don't have an account with the system?

    If you want to extend the system, you can let the instructor of a course assign 'invitations' to the currently registered members. So he really likes StudentA, adds him to his course, and gives him 2 invitations. Now StudentA can talk to his friends and see if anyone else is interested, go to the course webpage and add up to two of them.

     If you insist on doing invitation 'passwords', then your current scheme will work just fine.
    I can think of a whole bunch of ways of generating shorter keys, and no, I wouldn't want to write down an UUID someone is reading to me either.

    Since the objective is to make the passwords non-predictable, you'll have to use some kind of random or hashing function. As far as hashes go, MD5 is pretty standard, but not much better than UUIDs. CRC32 seems perfect, because it's short and not too complex. Crypt() might also work, but it'll be ugly as well.

    You can has the current date/time, but you have to make sure that the function doesn't run faster than the resolution of the timer. You can avoid that by using the current time, as a string, with numbers from 1 to X appended to it. If the hash function is any good, the one character difference will be more than enough.

    As for random words, this is really fun. Just generate a list of adjectives and one with nouns. Pick one from each, until you have enough. Words like OrangeBadger, Jollyllama or shinycar are trivially easy to say, write down, and remember.   
     



  • [quote user="baldheadedguy"]

    Thanks for the more in depth explanation, that helps.  Here's my suggestion.

    Since you own the website that people register through, is it not possible to create a private page in a secured area for the instructors of said course?  If so, I'd dump the idea of pre-generated keys and provide the isntructors with a UI in which they type the e-mail address of the person they want to invite to the course.

     The system can, then, send out an e-mail to that person containing a link to an invitation page, where they can register for the course.  The link would contain the invitation code as a get parameter to the page.

    Finally, I'd recommend that the invitation code be a hash of the person's e-mail address (or maybe even their first name, last name, and e-mail address).  Then, the invitation page could verify that the information typed in the page matched the invitation code given, so that only the person invited would be able to enroll in the course, even if the e-mail with the invitation code was forwarded on to another person.

    [/quote]

     

    I like the idea of sending an email containing a link, which contains the invitation code, to each person.  This would mean that the invitation code could be as long as I care to make it, and it wouldn't really be a problem, because all the user would have to do is click a link.  Currently, the enrollment page, where an invitation code (if needed) is requested of the user, isn't set up to take in querystring parameters, but that shouldn't be that difficult to do if I find time.

    I also like the idea of making the invitation a hash of the user's email address in order to ensure that only that user uses it, but that could cause problems.  For example, say the instructor sends out an invitation code to John Doe at 12345Doh@yeehaw.com.  John Doe clicks the link in the email which shoots him straight to the enrollment page, but wait, he's not logged in, so he gets taken back to the login page.  Worse yet, he's not even registered, so he has to set up an account before he can enroll.  So he sets up the account, then clicks the link in the email again, which should take him straight to the enrollment page, asking him to confirm that he really wants to enroll in Course D (the enrollment page at this point should have already taken his invitation code from the querystring and verfied it).  But what happens instead is that he gets a message telling him that his invitation code is invalid, and to try again.  The reason for this is that the invitation code has 12345DOH@yeehaw.com hashed into it, but when he registered, he registered with his work email address, John.Doe@SuperBigFortune500Company.com.

    The same thing could happen with a previously registered user if they decided to change their email address in our system between when the invitation code is created and when it is used.



  • [quote user="baldheadedguy"]

    After re-reading your statement about being able to provide the code 'however the instructor wants', maybe my suggestion doesn't quite fit the requirements... 

    [/quote]
    <font face="tahoma,arial,helvetica,sans-serif">I think it still does apply, the instructor then just have to be "creative" in sending out the invites like:</font>

    • <font face="tahoma,arial,helvetica,sans-serif">"Hey Joe, I have invited you to attend a course I would be teaching, check your email..."</font>
    • <font face="tahoma,arial,helvetica,sans-serif">"Hi Joe, this is your instructor speaking... Yes... I have sent you an invitation for a course that I would be teaching. Just check you email for the details..."</font>
    • <font face="tahoma,arial,helvetica,sans-serif">"Dear Joe, Please check you emails for I have invited you for a course I'd be teaching. Regards, instructor"</font>

    <font face="Tahoma">I think the instructor doesn't need to hand out the invitation codes other than through email because the invitees would still need to go online to enroll to the course thus, enrollees can just check their mails out and click the link or type in copy-paste the code invite in the email body.

    One more thing though, if the instructor can send out invites but needs to ensure that these people are the only one that can attend, I think it would be better if he just assign these people to the said course then create and distribute the invites (without any codes at all), then the "lucky ones" just need to fill in their account infos to confirm. For the people that doesn't have an account prior to the invitation, the instructor just needs to ask that person to create an account first then give him the details so he can assign him/her to the course. After all, if the person is not willing to create an account or study the course, the instructor have saved a slot for other people that's more willing to learn or interested in the course.



    </font>



  • [quote user="Nandurius"]

    It sounds like the invitation system is not
    up for debate, and I'd think that it's pretty sound. After all, it's
    pretty much along the lines of the various invitation-only services
    that pop up online every now and then.

    What you could consider is
    reverse-invitations. Rather than having the instructor give the student
    an invitation code, the student gives the instructor his system
    username. The instructor goes to the course administration page, clicks
    on 'add student', and the given account is added. Since registration is
    open to anyone, the students can register in advance, and it's much
    easier than doing it the other way around.

    [/quote]

    I'm
    not too keen this idea of reverse-invitations, for the following
    reason.  If the instructor wants John Doe to enroll in an invitation
    only course, he has to ask John Doe for his username.  If John Doe isn't
    registered with the system, he has to tell John Doe to first register
    with the system, then send his username to the instructor once
    registration is complete.  Once the instructor gets John Doe's
    username, he can then use it to add John Doe to the course.  With the
    current system, the instructor has to tell John Doe, "Hey, I think
    you'd like this course I'm teaching.  Go to www.TheSite.com and enroll
    in it.  It's invitation only, so here's a code you can use to get in." 
    After that, the instructor is done.  That seems easier, at least for
    the instructor, that the reverse-invitations system.  However, I might just be misunderstanding what you meant. 
    If so, please let me know.
     

    [quote user="Nandurius"]

    Is there any point in adding users that don't have an account with the system?

    [/quote]

    I'm not quite sure what you mean.

    [quote user="Nandurius"]

    If you insist on doing invitation 'passwords', then your current scheme will work just fine.
    I can think of a whole bunch of ways of generating shorter keys, and no, I wouldn't want to write down an UUID someone is reading to me either.

    Since the objective is to make the passwords non-predictable, you'll have to use some kind of random or hashing function. As far as hashes go, MD5 is pretty standard, but not much better than UUIDs. CRC32 seems perfect, because it's short and not too complex. Crypt() might also work, but it'll be ugly as well.

    You can has the current date/time, but you have to make sure that the function doesn't run faster than the resolution of the timer. You can avoid that by using the current time, as a string, with numbers from 1 to X appended to it. If the hash function is any good, the one character difference will be more than enough.

    As for random words, this is really fun. Just generate a list of adjectives and one with nouns. Pick one from each, until you have enough. Words like OrangeBadger, Jollyllama or shinycar are trivially easy to say, write down, and remember.
    [/quote]

    Thanks for the ideas!  Seriously, I positively never would have thought of the Adjective/Noun idea on my own!


Log in to reply