纯Javascript的PNG图形验证码生成组件(ASP Sample)

组件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
%
>

 

 

posted @ 2006-06-21 14:38  Rookie.Zhang  阅读(1927)  评论(1)    收藏  举报