C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)_第1頁
C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)_第2頁
C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)_第3頁
C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)_第4頁
C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)目錄使用背景:實現(xiàn)分析:后端代碼:準(zhǔn)備:使用:前端代碼:結(jié)語:

使用背景:

關(guān)于滑動驗證碼的使用場所還是非常多的,如:調(diào)取短信接口之前,和注冊請求之前或者頻繁會調(diào)用的接口都需要加這個拼圖驗證。這里先上一下效果圖吧(心中無碼,自然高清)。

話不多說,開擼!

實現(xiàn)分析:

滑動驗證碼的邏輯也很簡單。大概說一下:

1,服務(wù)器生成主圖+附圖(從主圖裁剪下來的不需要管y坐標(biāo))并且存儲X坐標(biāo);

2,前端傳入本地X坐標(biāo)到服務(wù)器。

3,服務(wù)器進(jìn)行計算存儲X坐標(biāo)和本地X坐標(biāo)相差值;

4,驗證相差值是否在0-2之間,判斷true|false

后端代碼:

準(zhǔn)備:

增加SlideCaptcha文件夾,并且增加Captcha.csCaptchaModel.csConfig.csImgFormat.cs4個文件。分別是:驗證,驗證實體,配置和圖片生成類。代碼如下:

Captcha.cs

usingSystem;

usingSystem.Drawing;

usingSystem.Drawing.Drawing2D;

usingSystem.Drawing.Imaging;

usingSystem.IO;

usingSystem.Net;

namespaceSliderCaptcha.NET

publicclassCaptcha

publicstaticCaptcha64ModelGenerateBase64()

CaptchaModelmodel=Captcha.Generate();

if(model!=null)

returnnewCaptcha64Model()

X=model.X,

Y=model.Y,

Background=ImageToBase64(model.Background,ImageFormat.Jpeg),

Slide=ImageToBase64(model.Slide,ImageFormat.Png)

else

returnnull;

///summary

///生成驗證碼

////summary

///returns/returns

publicstaticCaptchaModelGenerate()

Bitmapimage=BgImage();

if(image!=null)

intl=Config.l;

intd=Config.d;

intwidth=image.Width;

intheight=image.Height;

intx=RandomNext(width/3,width-d-l-10);//初始x

inty=RandomNext(10+d,height-l-10);;//初始y

GraphicsPathpath=GetSliderPath(x,y);

Graphicsg=GetGraphics(image);

//水印

if(Config.showWatermark)

Fontfont=newFont("宋體",12,FontStyle.Bold);

SizeFsize=g.MeasureString(Config.watermarkText,font);

PointPlogo=newPoint((int)(width-size.Width-5),(int)(height-size.Height-5));

Colorcolor=image.GetPixel(Plogo.X,Plogo.Y);

SolidBrushbru=newSolidBrush(AntiColor(color));

g.DrawString(Config.watermarkText,font,bru,Plogo);

Penpen=newPen(Color.FromArgb(200,255,255,255),2);

g.DrawPath(pen,path);

Imageslider=CaptureSlider(image,path,x,width,height);

SolidBrushbrush=newSolidBrush(Color.FromArgb(100,255,255,255));

g.FillPath(brush,path);

g.Save();

g.Dispose();

returnnewCaptchaModel()

X=x,

Y=y,

Background=image,

Slide=slider

returnnull;

///summary

///獲取圖片Graphics

////summary

///paramname="image"/param

///returns/returns

privatestaticGraphicsGetGraphics(Imageimage)

Graphicsg=Graphics.FromImage(image);

g.SmoothingMode=SmoothingMode.HighQuality;

g.CompositingQuality=CompositingQuality.HighQuality;

g.InterpolationMode=InterpolationMode.High;

returng;

///summary

///獲取滑塊path

////summary

privatestaticGraphicsPathGetSliderPath(intx,inty)

intl=Config.l;

intr=Config.r;

intb=Config.b;

intc=Config.c;

intd=Config.d;

intblod=Config.blod;

GraphicsPathpath=newGraphicsPath(FillMode.Winding);

PointPa=newPoint(x,y);

PointPb=newPoint(x+l/2-b,y-c+blod);

PointPd=newPoint(x+l,y);

PointPe=newPoint(Pd.X+c-blod,y+l/2-b);

PointPg=newPoint(Pd.X,y+l);

PointPh=newPoint(x,y+l);

PointPj=newPoint(x+c-blod,Pe.Y);

path.AddLine(Pa,Pb);

path.AddArc(x+l/2-r,y-d,d,d,130f,280f);

path.AddLines(newPoint[]{Pd,Pe});

path.AddArc(x+l,y+l/2-r,d,d,220f,280f);

path.AddLines(newPoint[]{Pg,Ph});

path.AddArc(x,y+l/2-r,d,d,140f,-280f);

path.AddLine(Pj,Pa);

returnpath;

///summary

///獲取滑塊區(qū)域

////summary

///paramname="image"/param

///paramname="path"/param

///paramname="x"/param

///paramname="width"/param

///paramname="height"/param

///returns/returns

privatestaticImageCaptureSlider(Imageimage,GraphicsPathpath,intx,intwidth,intheight)

Bitmapconcave=newBitmap(image.Width,image.Height);

Graphicsg=GetGraphics(concave);

TextureBrushbrush=newTextureBrush(image);

g.Clear(Color.Transparent);

g.FillPath(brush,path);

g.Dispose();

returnCaptureImage(concave,x,height);

///summary

///裁剪圖片

////summary

///paramname="fromImage"/param

///paramname="offsetX"/param

///paramname="width"/param

///paramname="height"/param

///returns/returns

privatestaticImageCaptureImage(ImagefromImage,intoffsetX,intheight)

intwidth=Config.l+Config.d+Config.blod;

Bitmapbitmap=newBitmap(width,height);

Graphicsg=GetGraphics(bitmap);

g.DrawImage(fromImage,0,0,newRectangle(offsetX,0,width,height),GraphicsUnit.Pixel);

g.Dispose();

returnbitmap;

///summary

///生成隨機數(shù)

////summary

///paramname="min"/param

///paramname="max"/param

///returns/returns

privatestaticintRandomNext(intmin,intmax)

Randomrandom=newRandom(Guid.NewGuid().GetHashCode());

returnrandom.Next(min,max);

///summary

///取反色

////summary

///paramname="color"/param

///returns/returns

publicstaticColorAntiColor(Colorcolor)

if(color.R128color.G128color.B128)

returnColor.Black;

else

returnColor.White;

///summary

///獲取背景圖

////summary

///returns/returns

privatestaticBitmapBgImage()

WebClientweb=newWebClient();

intnum=RandomNext(1,20);

Streamstream=web.OpenRead($"http://00/images/Pic/{num}.jpg");

Bitmapbitmap=(Bitmap)Image.FromStream(stream);

returnbitmap;

///summary

///base64轉(zhuǎn)圖片

////summary

///paramname="base64string"/param

///returns/returns

publicstaticBitmapBase64ToImage(stringbase64string)

byte[]b=Convert.FromBase64String(base64string);

MemoryStreamms=newMemoryStream(b);

Bitmapbitmap=newBitmap(ms);

returnbitmap;

///summary

///圖片轉(zhuǎn)base64

////summary

///paramname="image"/param

///returns/returns

publicstaticstringImageToBase64(Imageimage,ImageFormatformat)

if(image==null)returnstring.Empty;

stringstrbaser64="";

stringhead="";

stringformatName=ImgFormat.NameFromGuid(format);

head=$"data:image/{formatName.ToLower()};base64,";

MemoryStreamms=newMemoryStream();

image.Save(ms,format);

byte[]arr=newbyte[ms.Length];

ms.Position=0;

ms.Read(arr,0,(int)ms.Length);

ms.Close();

strbaser64=head+Convert.ToBase64String(arr);

catch(Exception)

thrownewException("Somethingwrongduringconvert!");

returnstrbaser64;

}

CaptchaModel.cs

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

namespaceSliderCaptcha.NET

publicclassCaptchaModel

publicintX{get;set;}

publicintY{get;set;}

publicImageBackground{get;set;}

publicImageSlide{get;set;}

publicclassCaptcha64Model

publicintX{get;set;}

publicintY{get;set;}

publicstringBackground{get;set;}

publicstringSlide{get;set;}

}

usingSystem;

namespaceSliderCaptcha.NET

publicclassConfig

///summary

///矩形寬

////summary

publicstaticintl=42;

///summary

///圓形半徑

////summary

publicstaticintr=9;

///summary

///圓形直徑

////summary

publicstaticintd=r*2;

///summary

///計算圓形與矩形交接三角形邊

////summary

publicstaticinta=(int)(r*Math.Sin(Math.PI*(50/180f)));

publicstaticintb=(int)(r*Math.Cos(Math.PI*(50/180f)));

publicstaticintc=r-a;

///summary

///滑塊邊框

////summary

publicstaticintblod=2;

///summary

///水印

////summary

publicstaticstringwatermarkText="SC.NET";

///summary

///是否顯示水印

////summary

publicstaticboolshowWatermark=true;

}

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Drawing.Imaging;

namespaceSliderCaptcha.NET

publicclassImgFormat

privatestaticDictionarystring,stringFormats=newDictionarystring,string(){

{"b96b3caa-0728-11d3-9d7b-0000f81ef32e","MemoryBmp"},

{"b96b3cab-0728-11d3-9d7b-0000f81ef32e","Bmp"},

{"b96b3cac-0728-11d3-9d7b-0000f81ef32e","Emf"},

{"b96b3cad-0728-11d3-9d7b-0000f81ef32e","Wmf"},

{"b96b3cae-0728-11d3-9d7b-0000f81ef32e","Jpeg"},

{"b96b3caf-0728-11d3-9d7b-0000f81ef32e","Png"},

{"b96b3cb0-0728-11d3-9d7b-0000f81ef32e","Gif"},

{"b96b3cb1-0728-11d3-9d7b-0000f81ef32e","Tiff"},

{"b96b3cb2-0728-11d3-9d7b-0000f81ef32e","Exif"},

{"b96b3cb5-0728-11d3-9d7b-0000f81ef32e","Icon"}

publicstaticImageFormatFormatFromGuid(ImageFormatformat)

returnFormatFromGuid(format.Guid);

publicstaticImageFormatFormatFromGuid(Guidguid)

returnFormatFromGuid(guid.ToString());

publicstaticImageFormatFormatFromGuid(stringguid)

if(Formats.ContainsKey(guid))

stringname=Formats[guid];

ImageFormatformat=null;

switch(name)

case"MemoryBmp":

format=ImageFormat.MemoryBmp;

break;

case"Bmp":

format=ImageFormat.Bmp;

break;

case"Emf":

format=ImageFormat.Emf;

break;

case"Wmf":

format=ImageFormat.Wmf;

break;

case"Gif":

format=ImageFormat.Gif;

break;

case"Jpeg":

format=ImageFormat.Jpeg;

break;

case"Png":

format=ImageFormat.Png;

break;

case"Tiff":

format=ImageFormat.Tiff;

break;

case"Exif":

format=ImageFormat.Exif;

break;

case"Icon":

format=ImageFormat.Icon;

break;

returnformat;

else

returnnull;

publicstaticstringNameFromGuid(ImageFormatformat)

returnNameFromGuid(format.Guid);

publicstaticstringNameFromGuid(Guidguid)

returnNameFromGuid(guid.ToString());

publicstaticstringNameFromGuid(stringguid)

if(Formats.ContainsKey(guid))

returnFormats[guid];

else

returnstring.Empty;

}

使用:

這里用的是mvc的框架,用的是api接口,前后端分離供前端使用。具體使用根據(jù)個人需求,可以是接口調(diào)用亦可以是項目調(diào)用。

呼聲如果很高的話,考慮出一個winfrom版本的滑動驗證碼~(滑稽)

[HttpGet]

publicIHttpActionResultGetCaptcha()

Captcha64Modelmodel=Captcha.GenerateBase64();

CacheHelper.Cache.SetCache("sliderX",model.X);

Hashtableht=newHashtable();

ht.Add("background",model.Background);

ht.Add("slider",model.Slide);

ht.Add("sliderXXXXX",model.X);

returnJson(ht);

///summary

///檢查驗證

////summary

///paramname="x"/param

///returns/returns

[HttpPost]

publicIHttpActionResultCheckCaptcha([FromBody]intx=0)

Hashtablehs=newHashtable();

stringMess="";

intCode=0;

varsession=CacheHelper.Cache.GetCache("sliderX");

if(session==null)

Mess="請刷新驗證碼";

Code=500;

gotoblock;

stringsliderXStr=session.ToString();//asstring

intsliderX=Convert.ToInt32(sliderXStr);

intdifX=sliderX-x;

if(difX=0-Config.bloddifX=Config.blod)

Mess="success";

Code=0;

else

session=null;

Mess="錯誤";

Code=500;

block:

hs.Add("Mess",Mess);

hs.Add("Code",Code);

returnJson(hs);

}

前端代碼:

!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"

html

head

titleSplideCaptcha/title

style

-webkit-user-select:none;

-moz-user-select:none;

-ms-user-select:none;

user-select:none;

.sc-captcha{

width:300px;

margin:100pxauto;

.sc_net_panel{

padding:10px;

.sc_net_paneldiv{

position:relative;

.bg_slider{

position:absolute;

left:0;

top:0;

.bg_refresh{

position:absolute;

right:5px;

top:5px;

background:#808080;

color:#fff;

border-radius:3px;

width:16px;

line-height:16px;

text-align:center;

cursor:pointer;

.sc_net_slider_icon{

position:absolute;

left:0;

top:0;

height:37px;

text-align:center;

border-radius:5px;

border:#8080801pxsolid;

width:37px;

line-height:37px;

cursor:pointer;

.sc_net_slider_icon:hover{

color:#fff;

background:#1991fa;

.sc_net_slider_text{

position:absolute;

left:0;

top:0;

text-align:center;

width:280px;

color:#45494c;

border:#8080801pxsolid;

border-radius:5px;

line-height:35px;

height:37px;

cursor:default;

.sc_net_slider_area{

position:absolute;

left:0;

top:0;

height:37px;

/style

scriptsrc="E:\porject\碚煜Api\ByzkApi\Scripts\jquery-3.4.1.js"/script

scriptsrc="E:\porject\碚煜Api\ByzkApi\Scripts\jquery-3.4.1.min.js"/script

/head

body

div

div

div

div

div

/div

divtitle="刷新"?/div

/div

/div

div

div

div向右拖動滑塊填充拼圖/div

div/div

div?/div

/div

/div

/div

/div

/body

script

loadCaptcha();

functionloadCaptcha(){

$.ajax({

url:"16:5500/api/TestApi/GetCaptcha",

type:"Get",

dataType:"JSON",

success:function(json){

varbg=createCanvas(280,155);

bg.className='bg_img';

bg_slider=createCanvas(62,155);

bg_slider.className='bg_slider';

CanvasSetImage(bg,json.background);

CanvasSetImage(bg_slider,json.slider);

vardoc=document.getElementsByClassName("sc_net_bgimg")[0];

doc.innerHTML="";

doc.appendChild(bg);

doc.appendChild(bg_slider);

console.log(json.modelX);

functioncreateCanvas(width,height){

varcanvas=document.createElement('canvas');

canvas.width=width;

canvas.height=height;

returncanvas;

functionCanvasSetImage(_canvas,base64){

//獲取2d畫布對象

varctx=_canvas.getContext("2d");

//創(chuàng)建圖片標(biāo)簽

var_img=document.createElement("img");

//設(shè)置圖片地址

_img.src=base64;

//ctx.fillRect(0,0,_canvas.clientWidth,_canvas.clientHeight);

//ctx.fillStyle='rgba(255,255,255,0)';

_img.onload=function(){

ctx.drawImage(_img,0,0);

/*ctx.drawImage(_img,10,10);*/

functiongetByClassName0(className){

returndocument.getElementsByClassName(className)[0];

varslider=getByClassName0("sc_net_slider_icon");

vartext=getByClassName0("sc_net_slider_text");

vararea=getByClassName0("sc_net_slider_area");

varbg_slider;

slider.addEventListener('mousedown',handleDragStart);

slider.addEventListener('touc

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論