首先在写代码之前我们来说一下验证码的由来:
老网民们大概都记得,刚开始上网的时候,是不存在验证码(capcha)这么一种东西的。这造成的结果是,垃圾评论和垃圾邮件可以轻松通过任何一个网站的注册程序,通过各种方式轰炸人民群众的眼球。
最先想要解决这一问题的是雅虎——作为互联网时代早期最重要的免费邮件提供商,他们一方面要解决用户们每天遇到的数以百计的垃圾邮件轰炸,另一方面,他们自己的免费邮箱,恰恰又是垃圾邮件的最爱——耗费无数资源所阻止的垃圾邮件,都来自于自己的服务器。这让雅虎开始认真考虑如何解决人机辨识问题。
他们找到一位当时刚刚21岁的天才——Luis von Ahn。 而Luis Von Ahn给出的方案,就是这个让人民群众微微皱眉,但是让计算机耸肩挠头的验证码 Capcha。计算机辨识技术还很落后,对于经过扭曲、污染的文字,无法辨识。而人类却可以轻松认出这些文字。这是一个简单而巧妙的设计,计算机先是产生一个随机的字符串,然后用程序把这个字符串的图像进行随机的污染,扭曲,再显示给显示器前的人或者机器。凡是能够辨识这些字符的,即为人类。
故事还没完,Luis Von Ahn是那种追求完美的科学家。当全世界数以十亿计的人每天都会浪费几秒钟的时间参与辨认文字这一简单活动的时候,他开始思考,其中浪费的人脑智力是否能得到更好的应用呢?
Luis Von Ahn的最终设计是,让人们用这些脑力解决一些计算机无法解决的图书数字化。
在计算机时代以前,印刷术已经存在了数百年,但这些印刷术所产生的书本和报纸等等,对于计算机来说都是模拟信号,仅以图像的形式存在,而非以数字化的形式存在。但是,早期的印刷术并不精确,文字大小不一,形象有差别。而且因为印刷品年代久远,拥有各种细微的缺损和污染。这对人眼来说不是什么大问题,但对计算机来说就麻烦了。
目前在google、yahoo、youtube等各个网站都能看到的双capcha,一个是需要辨认的文档图像,一个是计算机生成的capcha
因此,2002年,luis Von Ahn开始让capcha引用各种无法被计算机辨识的文字图像,目前,已经有上万网站采用他的新一代capcha。每天帮助辨识数以百万计的古老文档。
问题在于,对于最初的capcha来说,计算机实际上是知道答案的。而Luis希望人们辨识的文字,计算机实际上是不知道答案的,那如何能验证返回的答案到底是不是真的呢?
解决这个问题的方法依然体现了Luis一贯的简洁和优美,他让人们每次辨识两个,而非一个capcha,其中一个来自于计算机随机生成的字符串,而另一个则是从文档中选取的计算机不认识的字符图像。只要人们对前一个字符串给出的答案是正确的,那么就判定,人们对后一个capcha的辨识是正确的。
用这一方法,luis的capcha2.0 已经帮助完成了整个纽约时报130年的报纸存档数字化——这一本可能花费无数时间和资源的工程,在几个月之内就由各位网友们完成了。
当然,这是美国人在capcha中找到的人肉商机。而相对的,知道中国人和印度人怎么从capcha中寻找人肉商机吗?
简单来说,通过一系列程序转换,亚洲劳动密集型产业把各种垃圾邮件注册、电子游戏金币农民所需要解决的capcha辨认问题,集中给几个专门负责辨认capcha的人手里,这些人的工作就是,替垃圾邮件注册软件辨认capcha,一遍他们能冒充人类,每辨认一个获得半个卢比,每天需要辨认成千上万个capcha。
劳动密集型经济体和资本密集型经济体对人类脑力就是如此区别定价的。
下面我实现了一个伪验证码的实现方式:
HTML/CSS代码
<html>
<head>
<title>验证码</title>
<meta charset="utf-8">
<style type="text/css">
label{
width: 50px;
display: inline-block;
text-align: center;
}
input#rightcode{
font-family: Arial;
font-style: italic;
color: red;
padding: 2px 3px;
letter-spacing: 2px;
font-weight: bolder;
}
</style>
<script type="text/javascript" src="student.js"></script>
</head>
<body>
<div>
<form method="post">
<label for="num">账号</label>
<input name="num" type="text"><br/>
<label for="password">密码</label>
<input name="password" type="text"><br/>
<label for="yan">验证码</label>
<input type="text" name="yan" id="yan">
<input type="button"id="rightcode" value="" onclick="createNewCode()"><br>
<input type="button" value="登录" class="login" onclick="validate()" >
</form>
</div>
</body>
</html>
JS代码
/**
* Created by lenovo on 2017/4/24.
*/
var str;
var createNewCode = function () {
var arr = ['0','1','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
str = "";
var strlength = 4;
for(var i = 0; i < strlength; i++)
{
var num = Math.floor(Math.random()*arr.length);
str+= arr[num];
};
var btn = document.getElementById("rightcode");
btn.value = str;
}
window.onload = createNewCode;
function validate() {
var yan = document.getElementById('yan');
if(yan.value.toLowerCase() == str.toLowerCase())
alert("验证通过");
else
alert("验证码失败");
}
这里我实现的是一种hack式的代码,并没有达到可以作为实际应用的代码,因为这个方法实现的验证码可以在电脑中读取出来,与当初设计验证码的初衷并没有达到一致,现在实现的只是一种形式上的实现,但是在功能上还是有很大的差距。所以如果各位大佬如果有什么指教,欢迎留言评论。