用node做web开发很多都可能碰到需要验证码的地方,之前在github上搜索,有一些比如node-captcha等的类库,都需要依赖第三方的图形处理库或者软件,像我之前安装cario这个图形库时,真是费了好大一番劲,但是其实我们只用到了这些图形库的一点点小功能,比如图片的尺寸修改裁剪,或者生产验证码。
先介绍一下CImg这个c++的图形库吧,CImg是一个跨平台的C++的图像处理库,提供了加载、处理、显示、保存等一系列功能,最吸引人的地方是整个图形库就一个CImg.h这个文件,所以非常的便携绿色环保,带到哪里都可以进行编译使用,不用安装一大推依赖。于是我就想利用这个CImg图形库做一个简单的demo,就从实现验证码这个功能入手,当然可以完全利用这个库来做裁剪图片等其他功能。
ccap模块是基于CImg图形库的封装,让它可以供node使用,由于CImg图形库的便携性,所以ccap模块可以完全不依赖其他任何第三方图形库或者软件而独立工作,也就说如果只是想要生成简单的验证码,只要require这个ccap模块即可。
生成的图片示例:
1、安装: 通用方法:npm install ccap 或者通过github下载,地址:https://github.com/DoubleSpout/ccap 博客地址:http://snoopyxdy.blog.163.com/blog/static/60117440201301842110923/
2、性能: 在2cpu的linux 64位服务器上生成验证码速度可以达到1200次/秒,测试生成的图片是BMP的,jpeg的图片验证码生成速度大约在600次/秒。
3、声明方法:
var ccap = require('ccap');
var captcha1 = ccap();
var captcha2 = ccap(width, height, offset);
var captcha3 = ccap({
width:256,//set width,default is 256
height:60,//set height,default is 60
offset:40,//set text spacing,default is 40
quality:100,//set pic quality,default is 50
generate:function(){//Custom the function to generate captcha text
//generate captcha text here
return text;//return the captcha text
}
});
可以通过上述代码实例化一个ccap类。 1、不传任何参数,全部使用默认的参数进行生成验证码 2、只传递宽,高,偏移进行实例化,调整图片的大小,和图片中文字的间隔 3、传递一个对象,除了宽,高和偏移,还传递了图片质量以及生成随机数的方法,ccap模块会根据自定义函数return的字符串作为图片验证码的内容,默认是0-9,A-Z的6位随即字符串。
理论上可以生产很多不同的ccap的实例,而且他们之间互相没有影响,所以即使是通过cluster开启多进程的node同时生产验证码也不存在互相锁止的影响。
对于图片质量只对jpeg图片有效,如果没有安装任何jpeg的lib库的话,只能使用bmp未压缩图形了,体积比较大,但是生成速度比较快。
4、使用方法,get():
var ccap = require('ccap');
var captcha = ccap();
var ary = captcha.get();//ary[0] is captcha's text,ary[1] is captcha picture buffer.
var text = ary[0];
var buffer = ary[1];
实例化ccap类之后,会得到captcha对象,这个对象只有一个对外方法,get(),这个方法每次调用都会返回验证码buffer和对应的text字符串内容,保存在数组里,类似这样的结构:
["captcha text","picture buffer"]
5、一个简单的web例子:
var http = require('http');
var ccap = require('ccap')();//Instantiated ccap class
http.createServer(function (request, response) {
if(request.url == '/favicon.ico')return response.end('');//Intercept request favicon.ico
var ary = ccap.get();
var txt = ary[0];
var buf = ary[1];
response.end(buf);
console.log(txt);
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
上面这个例子会将验证码返回给客户端,并且把对应的验证码的文字输出出来,同时拦截了favicon.ico的请求。
结果如下图:
有兴趣的TX可以下载下来试试,如果安装有jpeg库的话,可以把根目录下的binding.jpeg.gyp覆盖改名为binding.gyp然后rebuild就可以使用jpeg图片作为验证码了,体积会小很多。另外ccap模块做了一些缓存的机制,尽量发挥更好的性能。
目前ccap已经对linux系统支持jpeg验证码,体积从45kb直降到6kb,欢迎下载试用,有任何问题请留言 ccap使用libjpeg库
看来很有用的小工具。 安装很好,可是运行出错:
$ node webtest.js
fs.js:338
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT, no such file or directory '../binding.gyp'
at Object.fs.openSync (fs.js:338:18)
at Object.fs.readFileSync (fs.js:182:15)
at Object.<anonymous> (/home/yliu0/dev/node_modules/ccap/lib/hcap.js:34:25)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
$ cat webtest.js
var http = require('http');
var ccap = require('ccap')();//Instantiated ccap class
http.createServer(function (request, response) {
if(request.url == '/favicon.ico')return response.end('');//Intercept request favicon.ico
var ary = ccap.get();
var txt = ary[0];
var buf = ary[1];
response.end(buf);
console.log(txt);
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
重新安装,还是有问题。也许你的运行环境不在Linux下,所以没有权限问题。 我建立了cap_img目录,给了全部权限 (full access). 还是出错。
$ node webtest.js
fs.js:582
return binding.unlink(pathModule._makeLong(path));
^
Error: EACCES, permission denied '/home/yliu0/dev/node_modules/ccap/cap_img/captcha_0_20185_0.bmp'
at Object.fs.unlinkSync (fs.js:582:18)
at dir (/home/yliu0/dev/node_modules/ccap/lib/dir.js:11:6)
at Array.forEach (native)
at dir (/home/yliu0/dev/node_modules/ccap/lib/dir.js:10:12)
at Object.<anonymous> (/home/yliu0/dev/node_modules/ccap/lib/hcap.js:159:1)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
$ ll
total 16
drwxrwxr-x 3 yliu0 yliu0 4096 Jan 19 00:35 ./
drwxrwxr-x 32 yliu0 yliu0 4096 Jan 18 11:35 ../
drwxrwxrwx 2 yliu0 yliu0 4096 Jan 19 00:35 cap_img/
-rw-rw-r-- 1 yliu0 yliu0 359 Jan 19 00:35 webtest.js
@leapon 我也是用centos 64位系统开发的啊,没发现这个问题,这个报错是node进程没有权限删除node_moudles/ccap/cat_img文件夹下的图片文件引起的 尝试用root权限启动node 手动删除上面文件夹下的所有图片文件再试试
我用的是 Ubuntu 64bit. 和 centos 64位 应该差别不大。 我的报错文件夹下一直是空的。
yliu0@u12:~/dev/test/node-module/captcha$ tree
.
├── cap_img
└── webtest.js
1 directory, 1 file
yliu0@u12:~/dev/test/node-module/captcha$ node webtest.js
fs.js:582
return binding.unlink(pathModule._makeLong(path));
^
Error: EACCES, permission denied '/home/yliu0/dev/node_modules/ccap/cap_img/captcha_0_20185_0.bmp'
at Object.fs.unlinkSync (fs.js:582:18)
at dir (/home/yliu0/dev/node_modules/ccap/lib/dir.js:11:6)
yliu0@u12:~/dev/test/node-module/captcha$ tree
.
├── cap_img
└── webtest.js
用 root 启动好用,还是权限的问题。
$ sudo node webtest.js
server starts...
RARP81
我还没写过 nodejs C/C++ 的模块,向你学习。
同样只能使用root才可以的路过,也是Ubuntu 64的。 安装的时候报了个错:
stderr: make install error: /usr/bin/install: cannot create regular file `/usr/local/lib/libjpeg.so.8.4.0': Permission denied
这个没关系,libjpeg我系统里已经装过了。但为什么用的时候要root权限?
我把模块下的那个文件夹权限设为700,再运行,报如下错:
[CImg] *** CImgIOException *** cimg::fopen(): Failed to open file '/home/zaobao/node_modules/ccap/cap_img/captcha_0_7243_0.jpeg' with mode 'wb'.
然后,那个文件夹权限变成dr----x–t了。
mac 下报着个错误。
In file included from ../addon/cap.cc:9:
…/addon/CImg-1.5.3/CImg.h:198:10: fatal error: ‘X11/Xlib.h’ file not found #include <X11/Xlib.h> ^ 1 error generated. make: *** [Release/obj.target/hcaptha/addon/cap.o] Error 1
本地测试都ok,然后部署上jitsu这个托管环境下会出错,我也不是很懂这个包是怎么制作的,但我有个疑问:为什么我用npm安装其它包的时候只是提示下载文件的信息,但是安装你这个我看了控制台输出怎么会有编译的提示呢? 下面是我在jitsu上看的出错日志:
gyp ERR! build error
gyp ERR! stack Error: make
failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/opt/local/lib/node_modules/npm/node_
modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:99:17)
gyp ERR! stack at Process._handle.onexit (child_process.js:678:10)
gyp ERR! System SunOS 5.11
gyp ERR! command “node” “/opt/local/lib/node_modules/npm/node_modules/node-gyp/b
in/node-gyp.js” “rebuild”
gyp ERR! cwd /root/tmp/tmp-23798gd7qxog/build/package/node_modules/ccap
gyp ERR! node -v v0.8.22
gyp ERR! node-gyp -v v0.9.5
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0
npm WARN package.json [email protected] No repository field. npm WARN package.json [email protected] No repository field. npm WARN package.json [email protected] bugs.email field must be a string email. Deleted. npm WARN package.json [email protected] No repository field. npm http GET https://registry.npmjs.org/ccap npm http 304 https://registry.npmjs.org/ccap
[email protected] preinstall /nodeweb/node/node_modules/ccap node make.js
I’m glad you to select ccap, enjoy it!
ccap is a cross plat form and portable nodejs simple captcha module, simple api and lightweight.
starting compile ccap! good luck!
[email protected] install /nodeweb/node/node_modules/ccap node-gyp rebuild
make:进入目录’/nodeweb/node/node_modules/ccap/build’
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jaricom.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcapimin.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcapistd.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcarith.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jccoefct.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jccolor.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcdctmgr.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jchuff.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcinit.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcmainct.o
…/addon/jpeglib/jcmainct.c: 在函数‘start_pass_main’中:
…/addon/jpeglib/jcmainct.c:71:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jcmainct.c: 在函数‘process_data_simple_main’中:
…/addon/jpeglib/jcmainct.c:117:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jcmainct.c: 在函数‘jinit_c_main_controller’中:
…/addon/jpeglib/jcmainct.c:247:15: 警告: ‘main’通常是一个函数 [-Wmain]
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcmarker.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcmaster.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcomapi.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcparam.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcprepct.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jcsample.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jctrans.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdapimin.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdapistd.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdarith.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdatadst.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdatasrc.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdcoefct.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdcolor.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jddctmgr.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdhuff.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdinput.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdmainct.o
…/addon/jpeglib/jdmainct.c: 在函数‘alloc_funny_pointers’中:
…/addon/jpeglib/jdmainct.c:162:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘make_funny_pointers’中:
…/addon/jpeglib/jdmainct.c:203:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘set_wraparound_pointers’中:
…/addon/jpeglib/jdmainct.c:243:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘set_bottom_pointers’中:
…/addon/jpeglib/jdmainct.c:272:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘start_pass_main’中:
…/addon/jpeglib/jdmainct.c:309:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘process_data_simple_main’中:
…/addon/jpeglib/jdmainct.c:349:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘process_data_context_main’中:
…/addon/jpeglib/jdmainct.c:389:15: 警告: ‘main’通常是一个函数 [-Wmain]
…/addon/jpeglib/jdmainct.c: 在函数‘jinit_d_main_controller’中:
…/addon/jpeglib/jdmainct.c:478:15: 警告: ‘main’通常是一个函数 [-Wmain]
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdmarker.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdmaster.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdmerge.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdpostct.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdsample.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jdtrans.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jerror.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jfdctflt.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jfdctfst.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jfdctint.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jidctflt.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jidctfst.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jidctint.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jquant1.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jquant2.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jutils.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jmemmgr.o
CC(target) Release/obj.target/hcaptha/addon/jpeglib/jmemnobs.o
CXX(target) Release/obj.target/hcaptha/addon/hcaptha.o
CXX(target) Release/obj.target/hcaptha/addon/cap.o
In file included from …/addon/cap.cc:9:0:
…/addon/CImg-1.5.3/CImg.h:272:21: 致命错误: jpeglib.h:没有那个文件或目录
编译中断。
make: *** [Release/obj.target/hcaptha/addon/cap.o] 错误 1
make:离开目录“/nodeweb/node/node_modules/ccap/build”
gyp ERR! build error
gyp ERR! stack Error: make
failed with exit code: 2
gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:789:12)
gyp ERR! System Linux 3.2.0-45-generic
gyp ERR! command “node” “/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js” “rebuild”
gyp ERR! cwd /nodeweb/node/node_modules/ccap
gyp ERR! node -v v0.10.9
gyp ERR! node-gyp -v v0.9.6
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0
[email protected] install /home/renyuan/node_modules/ccap node-gyp rebuild
Traceback (most recent call last):
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp", line 1 in <module>
sys.exit(gyp.main(sys.argv[1:]))
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/it.py", line 523, in main
return gyp_main(args)
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/it.py", line 499, in gyp_main
options.circular_check)
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/it.py", line 129, in Load
params[‘parallel’])
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/int.py", line 2556, in Load
variables, includes, depth, check, True)
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/int.py", line 365, in LoadTargetBuildFile
includes, True, check)
File "/usr/local/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/int.py", line 223, in LoadOneBuildFile
None)
File "binding.gyp", line 1
{
^
SyntaxError: invalid syntax
gyp ERR! configure error
gyp ERR! stack Error: gyp
failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/ne_modules/node-gyp/lib/configure.js:415:16)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:7812)
gyp ERR! System Linux 2.6.32-220.13.1.el6.x86_64
gyp ERR! command “node” “/usr/local/lib/node_modules/npm/node_modules/node-gypin/node-gyp.js” “rebuild”
gyp ERR! cwd /home/renyuan/node_modules/ccap
gyp ERR! node -v v0.10.7
gyp ERR! node-gyp -v v0.9.5
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0
在win 下编译倒是没问题,在centos 6.4 64 位 发现了这个问题。。。
Mac下报错
In file included from …/addon/cap.cc:9: …/addon/jpeglib/CImg.h:198:10: fatal error: ‘X11/Xlib.h’ file not found #include <X11/Xlib.h>
@snoopy 根据我的实践,绝大部分挡不住滤波和字符切割的验证码,都没有意义。大幅度的平滑扭曲,紧凑无间距的字符布局,是目前最有效的验证码,google的验证码就是典型,不过据说前几天也被攻破了。我也在尝试用矢量特征+神经网络+贝叶斯特征库来测试,如果新闻所说不假,估计不久就能重现90%的识别率了
@DoubleSpout 在阿里云的ContOS6.3中,运行npm install ccap,报如下异常
npm http GET https://registry.npmjs.org/ccap npm http 304 https://registry.npmjs.org/ccap
I’m glad you to select ccap, enjoy it!
ccap is a cross plat form and portable nodejs simple captcha module, simple api and lightweight.
starting compile ccap! good luck! npm http GET https://registry.npmjs.org/node-schedule/0.1.13 npm http 304 https://registry.npmjs.org/node-schedule/0.1.13
[email protected] install /syt/nodejs/supercoach-web/node_modules/ccap node-gyp rebuild
Traceback (most recent call last):
File "/usr/bin/gyp", line 18, in <module>
sys.exit(gyp.main(sys.argv[1:]))
File "/usr/lib/python2.6/site-packages/gyp/init.py", line 462, in main
options.circular_check)
File "/usr/lib/python2.6/site-packages/gyp/init.py", line 100, in Load
depth, generator_input_info, check, circular_check)
File "/usr/lib/python2.6/site-packages/gyp/input.py", line 2255, in Load
depth, check)
File "/usr/lib/python2.6/site-packages/gyp/input.py", line 362, in LoadTargetBuildFile
includes, True, check)
File "/usr/lib/python2.6/site-packages/gyp/input.py", line 217, in LoadOneBuildFile
None)
File "binding.gyp", line 1
{
^
SyntaxError: invalid syntax
gyp ERR! configure error
gyp ERR! stack Error: gyp
failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (/usr/lib/node_modules/node-gyp/lib/configure.js:428:16)
gyp ERR! stack at ChildProcess.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:809:12)
gyp ERR! System Linux 2.6.32-431.20.3.el6.x86_64
gyp ERR! command “node” “/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js” “rebuild”
gyp ERR! cwd /syt/nodejs/supercoach-web/node_modules/ccap
gyp ERR! node -v v0.10.29
gyp ERR! node-gyp -v v0.10.6
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0
如何解决?