Currently we are running a competition which proceeds very well. Unfortunately we have all those cheaters back in business who are running scripts which automatically vote f
We use a combination of CAPTCHA and email. The user receive a link with a GUID by mail. This one must be unique for each user that try to vote. www.votesite.com/vote.aspx?guid=..... By using this link the vote is confirmed or not. In database we check the combination of email address and GUID to be unique.
Check out Asirra: http://research.microsoft.com/en-us/um/redmond/projects/asirra/ It's still in beta, but it's pretty cool.
If you're really worried about it then you have to do something like email verification, which might be sufficient to block most cheaters.
Also it depends whether multiple people behind a NAT are likely to want to vote for the same option (e.g. favourite school).
Any scheme you create can be gamed.
EDIT: As everyone else has suggested, you can use a CAPTCHA such as reCAPTCHA to block automated bots, and make humans less likely to repeat vote. At the cost of making humans less likely to vote at all.
You could add a honeypot field like in Django. Most likely, this will not protect you from cheaters who deliberately want to change your competition, but at least you will have lesser 'drive-by' spammers to additionally take care of.
1.Use recaptcha
2. Yes randomize your voting options but not like this:
-> from vote_id_1 to asdsasd_1, grdsgsdg_2,
Instead use session variables to set a mask from vote_id_1 to asgjdas87th2ad in the vote form.
CAPTCHA's aren't a silver bullet, the user could have their script display the CAPTCHA to them and solve them manually for at least several votes per minute.
You need to use them in combination with other techniques mentioned here.