下载地址:http://www.zf.net.tv/NetDisk/MakeFile.asp?ID=3
演示:http://www.zf.net.tv/Identify
说明:解压缩后需要右键“Identify.sct”注册。
在ASP.Net 2.0下失败(ASP.Net 2.0的Unicode.GetBytes处理数据时返回不标准的数据造成。)
源代码是国外一猛人用Javacript脚本写的ASP文件,我只是稍作加工,实现通用。
组件Identify.sct
<?xml version="1.0" encoding="utf-8"?>
<package>
<?component error="true" debug="true"?>
<comment>
<![CDATA[
纯Javascript生成的png图片组件
]]>
</comment>
<scriptlet id="Identify">
<registration progid="Javascript.PngIdentify" version="1.0" description="PNG验证码生成组件" remotable="true" />
<public>
<method name="MakePng" internalName="captcha">
<parameter name="str" />
</method>
<method name="MD5" internalName="hex_md5">
<parameter name="s" />
</method>
</public>
<script language="Javascript">
<![CDATA[
var ASCII=new Array(36);
ASCII[0] = "1110000111110111101111011110111101111011110111101111011110111101111011110111101111011110111110000111";
ASCII[1] = "1111011111110001111111110111111111011111111101111111110111111111011111111101111111110111111100000111";
ASCII[2] = "1110000111110111101111011110111111111011111111011111111011111111011111111011111111011110111100000011";
ASCII[3] = "1110000111110111101111011110111111110111111100111111111101111111111011110111101111011110111110000111";
ASCII[4] = "1111101111111110111111110011111110101111110110111111011011111100000011111110111111111011111111000011";
ASCII[5] = "1100000011110111111111011111111101000111110011101111111110111111111011110111101111011110111110000111";
ASCII[6] = "1111000111111011101111011111111101111111110100011111001110111101111011110111101111011110111110000111";
ASCII[7] = "1100000011110111011111011101111111101111111110111111110111111111011111111101111111110111111111011111";
ASCII[8] = "1110000111110111101111011110111101111011111000011111101101111101111011110111101111011110111110000111";
ASCII[9] = "1110001111110111011111011110111101111011110111001111100010111111111011111111101111011101111110001111";
ASCII[10] = "1111011111111101111111101011111110101111111010111111101011111100000111110111011111011101111000100011";
ASCII[11] = "1000000111110111101111011110111101110111110000111111011101111101111011110111101111011110111000000111";
ASCII[12] = "1110000011110111101110111110111011111111101111111110111111111011111111101111101111011101111110001111";
ASCII[13] = "0000001111110111011111011110111101111011110111101111011110111101111011110111101111011101110000001111";
ASCII[14] = "1000000111110111101111011011111101101111110000111111011011111101101111110111111111011110111000000111";
ASCII[15] = "1000000111110111101111011011111101101111110000111111011011111101101111110111111111011111111000111111";
ASCII[16] = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
![]()
var FONT_WIDTH=10;
var FONT_HEIGHT=10;
![]()
var WIDTH=160;
var HEIGHT=40;
var DEPTH=8;
var MAP=new Array((WIDTH+1)*HEIGHT);
![]()
function B4(b){
return String.fromCharCode((b>>24)&0xFF, (b>>16)&0xFF, (b>>8)&0xFF, b&0xFF);
}
function B2(b){
return String.fromCharCode((b>>8)&0xFF, b&0xFF);
}
function B1(b){
return String.fromCharCode(b&0xFF);
}
![]()
var CRC_TABLE=new Array(256);
// Make crc table
function CRC32_Init(){
var n=0, k=0;
var c;
for(n=0; n<256; n++){
c=n;
for(k=0; k<8; k++){
if (c&1)
c=0xedb88320^(c>>>1);
else
c=c>>>1;
}
CRC_TABLE[n]=c;
}
}
CRC32_Init();
![]()
function CRC32(str){
var c=0xFFFFFFFF;
var n=0;
for(n=0; n<str.length; n++){
c=CRC_TABLE[(c^str.charCodeAt(n))&0xFF]^(c>>>8);
}
return c^0xFFFFFFFF;
}
![]()
function png_signature(){
return [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
}
![]()
function png_chunk(type, str){
var ary=[], i=0;
var crc;
crc=CRC32(type+str);
str=B4(str.length)+type+str;
str=str+B4(crc);
for(i=0; i<str.length; i++)
ary.push(str.charCodeAt(i));
return ary;
}
![]()
function png_IHDR(){
return png_chunk("IHDR", B4(WIDTH)+B4(HEIGHT)+B1(DEPTH)+B1(3)+B1(0)+B1(0)+B1(0));
}
![]()
function png_PLTE(){
return png_chunk("PLTE",
B1(255)+B1(255)+B1(255) //0
+B1(224)+B1(224)+B1(224) //1
+B1(192)+B1(192)+B1(192) //2
+B1(160)+B1(160)+B1(160) //3
+B1(128)+B1(128)+B1(128) //4
+B1(96)+B1(96)+B1(96) //5
+B1(64)+B1(64)+B1(64) //6
+B1(32)+B1(32)+B1(32) //7
+B1(0)+B1(0)+B1(0) //8
);
}
![]()
function png_IDAT(){
var h=HEIGHT
var strip=WIDTH+1;
var x, y;
var data=""
for(y=0; y<h; y++) for(x=0; x<strip; x++)
data=data+String.fromCharCode(MAP[x+y*strip]);
var LEN=data.length;
var NLEN=LEN^0xFFFFFFFF;
// Calculate Simple Adler-32 checksum
var BASE=65521, NMAX=5552;
var s1=1, s2=0, n=NMAX;
var i;
for(i=0; i<LEN; i++){
s1+=data.charCodeAt(i);
s2+=s1;
if((n--)==0){
s1%=BASE;
s2%=BASE;
n=NMAX;
}
}
s1%=BASE;
s2%=BASE;
return png_chunk("IDAT", B1(0x78)+B1(0xDA)+B1(0x01)+ /*uncompressd lz77*/
String.fromCharCode((LEN)&0xFF, (LEN>>8)&0xFF, (NLEN)&0xFF, (NLEN>>8)&0xFF) +
data+B4((s2<<16)|s1));
}
![]()
function png_IEND(){
return png_chunk("IEND", "");
}
![]()
function png_output(){
var png=dat=[], i=0
var str="";
dat=dat.concat(png_signature(), png_IHDR(), png_PLTE(), png_IDAT(), png_IEND());
if(dat.length % 2==1) dat.push(0); // Fill data to make it 2-byte aligned
for(i=0; i<dat.length-1; i+=2){
png.push(String.fromCharCode( dat[i] + (dat[i+1]<<8) ));
}
return png.join("");
}
![]()
function Map_Init(){
var x, y;
var strip=WIDTH+1;
for(x=0; x<strip; x++) for(y=0; y<HEIGHT; y++){
if(x==0)
MAP[x+y*strip]=0; // scanline indicator
else
MAP[x+y*strip]=8; // bgcolor
}
}
![]()
function putPixel(x, y, c){
MAP[x+1+y*(WIDTH+1)]=c;
}
function getPixel(x, y, c){
return MAP[x+1+y*(WIDTH+1)];
}
![]()
function putChar(ox, oy, ch){
var x, y;
oy+=Math.floor(Math.random()*5-5.5);
for(y=0;y<FONT_HEIGHT;y++){
ox+=Math.floor(Math.random()*2+0.5)-1;
for(x=0;x<FONT_WIDTH;x++){
var c=1-parseInt(ASCII[ch].charAt(x+y*FONT_WIDTH));
if(c>0){
c=0;
// double size, bold and random italic
putPixel(ox+x*3, oy+y*2, c);
putPixel(ox+x*3+1, oy+y*2, c);
putPixel(ox+x*3+2, oy+y*2, c);
putPixel(ox+x*3, oy+y*2+1, c);
putPixel(ox+x*3+1, oy+y*2+1, c);
putPixel(ox+x*3+2, oy+y*2+1, c);
}
}
}
}
function putNoise(n, c){
var i, x, y;
for(i=0; i<n; i++){
x=Math.floor(Math.random()*WIDTH);
y=Math.floor(Math.random()*HEIGHT);
putPixel(x, y, c);
}
}
function smooth(){
var x, y;
var c0, c1, c2, c3, c4; // center, up, right, down, left
for(x=0; x<WIDTH; x++) for(y=0; y<HEIGHT; y++){
c0=getPixel(x, y);
c1=(y>0)?getPixel(x, y-1):c0;
c2=(x<WIDTH)?getPixel(x+1, y):c0;
c3=(y<HEIGHT)?getPixel(x, y+1):c0;
c4=(x>0)?getPixel(x-1, y):c0;
putPixel(x, y, Math.floor((c0*6+c1+c2+c3+c4)/10+0.5));
}
}
![]()
// MD5
var v1=0;var v2="";var v3=8;function hex_md5(s){return binl2hex(f2(f8(s),s.length*v3)).toUpperCase();}function b64_md5(s){return binl2b64(f2(f8(s),s.length*v3));}function str_md5(s){return binl2str(f2(f8(s),s.length*v3));}function hex_hmac_md5(key,data){return binl2hex(f9(key,data));}function b64_hmac_md5(key,data){return binl2b64(f9(key,data));}function str_hmac_md5(key,data){return binl2str(f9(key,data));}function f1(){return hex_md5("abc")=="900150983cd24fb0d6963f7d28e17f72";}function f2(x,len){x[len>>5]|=0x80<<((len)%32);x[(((len+64)>>>9)<<4)+14]=len;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(var i=0;i<x.length;i+=16){var olda=a;var oldb=b;var oldc=c;var oldd=d;a=f4(a,b,c,d,x[i+0],7,-680876936);d=f4(d,a,b,c,x[i+1],12,-389564586);c=f4(c,d,a,b,x[i+2],17,606105819);b=f4(b,c,d,a,x[i+3],22,-1044525330);a=f4(a,b,c,d,x[i+4],7,-176418897);d=f4(d,a,b,c,x[i+5],12,1200080426);c=f4(c,d,a,b,x[i+6],17,-1473231341);b=f4(b,c,d,a,x[i+7],22,-45705983);a=f4(a,b,c,d,x[i+8],7,1770035416);d=f4(d,a,b,c,x[i+9],12,-1958414417);c=f4(c,d,a,b,x[i+10],17,-42063);b=f4(b,c,d,a,x[i+11],22,-1990404162);a=f4(a,b,c,d,x[i+12],7,1804603682);d=f4(d,a,b,c,x[i+13],12,-40341101);c=f4(c,d,a,b,x[i+14],17,-1502002290);b=f4(b,c,d,a,x[i+15],22,1236535329);a=f5(a,b,c,d,x[i+1],5,-165796510);d=f5(d,a,b,c,x[i+6],9,-1069501632);c=f5(c,d,a,b,x[i+11],14,643717713);b=f5(b,c,d,a,x[i+0],20,-373897302);a=f5(a,b,c,d,x[i+5],5,-701558691);d=f5(d,a,b,c,x[i+10],9,38016083);c=f5(c,d,a,b,x[i+15],14,-660478335);b=f5(b,c,d,a,x[i+4],20,-405537848);a=f5(a,b,c,d,x[i+9],5,568446438);d=f5(d,a,b,c,x[i+14],9,-1019803690);c=f5(c,d,a,b,x[i+3],14,-187363961);b=f5(b,c,d,a,x[i+8],20,1163531501);a=f5(a,b,c,d,x[i+13],5,-1444681467);d=f5(d,a,b,c,x[i+2],9,-51403784);c=f5(c,d,a,b,x[i+7],14,1735328473);b=f5(b,c,d,a,x[i+12],20,-1926607734);a=f6(a,b,c,d,x[i+5],4,-378558);d=f6(d,a,b,c,x[i+8],11,-2022574463);c=f6(c,d,a,b,x[i+11],16,1839030562);b=f6(b,c,d,a,x[i+14],23,-35309556);a=f6(a,b,c,d,x[i+1],4,-1530992060);d=f6(d,a,b,c,x[i+4],11,1272893353);c=f6(c,d,a,b,x[i+7],16,-155497632);b=f6(b,c,d,a,x[i+10],23,-1094730640);a=f6(a,b,c,d,x[i+13],4,681279174);d=f6(d,a,b,c,x[i+0],11,-358537222);c=f6(c,d,a,b,x[i+3],16,-722521979);b=f6(b,c,d,a,x[i+6],23,76029189);a=f6(a,b,c,d,x[i+9],4,-640364487);d=f6(d,a,b,c,x[i+12],11,-421815835);c=f6(c,d,a,b,x[i+15],16,530742520);b=f6(b,c,d,a,x[i+2],23,-995338651);a=f7(a,b,c,d,x[i+0],6,-198630844);d=f7(d,a,b,c,x[i+7],10,1126891415);c=f7(c,d,a,b,x[i+14],15,-1416354905);b=f7(b,c,d,a,x[i+5],21,-57434055);a=f7(a,b,c,d,x[i+12],6,1700485571);d=f7(d,a,b,c,x[i+3],10,-1894986606);c=f7(c,d,a,b,x[i+10],15,-1051523);b=f7(b,c,d,a,x[i+1],21,-2054922799);a=f7(a,b,c,d,x[i+8],6,1873313359);d=f7(d,a,b,c,x[i+15],10,-30611744);c=f7(c,d,a,b,x[i+6],15,-1560198380);b=f7(b,c,d,a,x[i+13],21,1309151649);a=f7(a,b,c,d,x[i+4],6,-145523070);d=f7(d,a,b,c,x[i+11],10,-1120210379);c=f7(c,d,a,b,x[i+2],15,718787259);b=f7(b,c,d,a,x[i+9],21,-343485551);a=safe_add(a,olda);b=safe_add(b,oldb);c=safe_add(c,oldc);d=safe_add(d,oldd);}return Array(a,b,c,d);}function f3(q,a,b,x,s,t){return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b);}function f4(a,b,c,d,x,s,t){return f3((b&c)|((~b)&d),a,b,x,s,t);}function f5(a,b,c,d,x,s,t){return f3((b&d)|(c&(~d)),a,b,x,s,t);}function f6(a,b,c,d,x,s,t){return f3(b^c^d,a,b,x,s,t);}function f7(a,b,c,d,x,s,t){return f3(c^(b|(~d)),a,b,x,s,t);}function f9(key,data){var bkey=f8(key);if(bkey.length>16)bkey=f2(bkey,key.length*v3);var ipad=Array(16),opad=Array(16);for(var i=0;i<16;i++){ipad[i]=bkey[i]^0x36363636;opad[i]=bkey[i]^0x5C5C5C5C;}var hash=f2(ipad.concat(f8(data)),512+data.length*v3);return f2(opad.concat(hash),512+128);}function safe_add(x,y){var lsw=(x&0xFFFF)+(y&0xFFFF);var msw=(x>>16)+(y>>16)+(lsw>>16);return(msw<<16)|(lsw&0xFFFF);}function bit_rol(num,cnt){return(num<<cnt)|(num>>>(32-cnt));}function f8(str){var bin=Array();var mask=(1<<v3)-1;for(var i=0;i<str.length*v3;i+=v3)bin[i>>5]|=(str.charCodeAt(i/v3)&mask)<<(i%32);return bin;}function binl2str(bin){var str="";var mask=(1<<v3)-1;for(var i=0;i<bin.length*32;i+=v3)str+=String.fromCharCode((bin[i>>5]>>>(i%32))&mask);return str;}function binl2hex(binarray){var hex_tab=v1?"0123456789ABCDEF":"0123456789abcdef";var str="";for(var i=0;i<binarray.length*4;i++){str+=hex_tab.charAt((binarray[i>>2]>>((i%4)*8+4))&0xF)+hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&0xF);}return str;}function binl2b64(binarray){var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var str="";for(var i=0;i<binarray.length*4;i+=3){var triplet=(((binarray[i>>2]>>8*(i%4))&0xFF)<<16)|(((binarray[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((binarray[i+2>>2]>>8*((i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>binarray.length*32)str+=v2;else str+=tab.charAt((triplet>>6*(3-j))&0x3F);}}return str;}
![]()
function captcha(str){
Map_Init();
var ox=FONT_WIDTH/2, oy=(HEIGHT-FONT_HEIGHT)/2;
var i;
var idx=0;
var c;
for(i=0; i<str.length; i++){
c=str.charCodeAt(i);
if(c<=57 && c>=48)
idx=c-48;
else if(c<=70 && c>=65)
idx=c-65+10;
else idx=16;
putChar(ox+i*FONT_WIDTH*2.5, oy, idx);
}
putNoise(500, 4);
putNoise(500, 2);
smooth();
return png_output();
}]]>
</script>
</scriptlet>
</package>
调用页面Identify.asp
<%
Randomize
Response.CacheControl="no-cache"
Response.ContentType="image/png"
'Set Identify = GetObject("script:"&Server.MapPath("Identify.sct#Identify"))
Set Identify = Server.CreateObject("Javascript.PngIdentify")
rndStr=Left(Identify.MD5(cstr(rnd)),6)
Response.BinaryWrite Identify.MakePng(rndStr)
Set Identify=Nothing
%>