日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[原创]红马版验证码实现(中文+变形+噪点)

發布時間:2025/3/15 编程问答 87 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [原创]红马版验证码实现(中文+变形+噪点) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
為了應付越來越多的自動發帖機、惡意攻擊等情形,驗證碼技術在大量的網站上得到使用。我在近期開發一個注冊網站的時候,也使用了這一技術。當然,我并不想完完全全自己重新實現,而是參考了網上能夠找到的實現,做了若干改進而已。下面談談我的實現。
??? 補兩張圖片:
??? ??
??? 首先看驗證碼圖片輸出頁的代碼:
<%@?Page?Language="C#"?%>

<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script?runat="server">
????
protected?void?Page_Load(object?sender,?EventArgs?e)
????{
????????VryImgGen?gen?
=?new?VryImgGen();
????????
string?verifyCode?=?gen.CreateVerifyCode(5,?1);
????????Session[
"VerifyCode"]?=?verifyCode.ToUpper();
????????System.Drawing.Bitmap?bitmap?
=?gen.CreateImage(verifyCode);
????????System.IO.MemoryStream?ms?
=?new?System.IO.MemoryStream();
????????bitmap.Save(ms,?System.Drawing.Imaging.ImageFormat.Png);
????????Response.Clear();
????????Response.ContentType?
=?"image/Png";
????????Response.BinaryWrite(ms.GetBuffer());
????????bitmap.Dispose();
????????ms.Dispose();
????????ms.Close();
????????Response.End();
????}
</script> ??? 功能很簡單,初始化一個驗證碼生成對象,生成圖片。然后保存到一個MemoryStream里。得到字節流,輸出字節流。驗證碼的數據是保存在Session中的,這是最簡單的方法?;蛘呖梢约用軆Υ嬖赾ookie里,也是可以的。

??? 再來看看驗證碼生成對象: using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
using?System.Drawing;
using?System.Text;

///?<summary>
///?Summary?description?for?VryImgGen
///?</summary>
public?partial?class?VryImgGen
{
????
????
///?<summary>
????
///?供驗證碼生成漢字時選取的漢字集,若為空則按照《GB2312簡體中文編碼表》編碼規則構造漢字
????
///?</summary>
????public?static?string?ChineseChars?=?String.Empty;

????
///?<summary>
????
///?英文與數字串
????
///?</summary>
????protected?static?readonly?string?EnglishOrNumChars?=?"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
???
????
public?VryImgGen()
????{
????????rnd?
=?new?Random(unchecked((int)DateTime.Now.Ticks));
????}

????
///?<summary>
????
///?全局隨機數生成器
????
///?</summary>
????private?Random?rnd;
????
????
int?length?=?5;
????
///?<summary>
????
///?驗證碼長度(默認6個驗證碼的長度)
????
///?</summary>
????public?int?Length
????{
????????
get?{?return?length;?}
????????
set?{?length?=?value;?}
????}
????????
????
int?fontSize?=?18;
????
///?<summary>
????
///?驗證碼字體大小(為了顯示扭曲效果,默認30像素,可以自行修改)
????
///?</summary>
????public?int?FontSize
????{
????????
get?{?return?fontSize;?}
????????
set?{?fontSize?=?value;?}
????}???
????
????
int?padding?=?4;
????
///?<summary>
????
///?邊框補(默認4像素)
????
///?</summary>
????public?int?Padding
????{
????????
get?{?return?padding;?}
????????
set?{?padding?=?value;?}
????}???
????
????
bool?chaos?=?true;
????
///?<summary>
????
///?是否輸出燥點(默認輸出)
????
///?</summary>
????public?bool?Chaos
????{
????????
get?{?return?chaos;?}
????????
set?{?chaos?=?value;?}
????}???
????????
????Color?chaosColor?
=?Color.LightGray;
????
///?<summary>
????
///?輸出燥點的顏色(默認灰色)
????
///?</summary>
????public?Color?ChaosColor
????{
????????
get?{?return?chaosColor;?}
????????
set?{?chaosColor?=?value;?}
????}
????
????Color?backgroundColor?
=?Color.White;
????
///?<summary>
????
///?自定義背景色(默認白色)
????
///?</summary>
????public?Color?BackgroundColor
????{
????????
get?{?return?backgroundColor;?}
????????
set?{?backgroundColor?=?value;?}
????}???
????????
????Color[]?colors?
=?{?Color.Black,?Color.Red,?Color.DarkBlue,?Color.Green,?Color.Orange,?Color.Brown,?Color.DarkCyan,?Color.Purple?};
????
///?<summary>
????
///?自定義隨機顏色數組
????
///?</summary>
????public?Color[]?Colors
????{
????????
get?{?return?colors;?}
????????
set?{?colors?=?value;?}
????}
??
????
string[]?fonts?=?{?"Arial",?"Georgia"?};
????
///?<summary>
????
///?自定義字體數組
????
///?</summary>
????public?string[]?Fonts
????{
????????
get?{?return?fonts;?}
????????
set?{?fonts?=?value;?}
????}???

????
#region?產生波形濾鏡效果

????
private?const?double?PI?=?3.1415926535897932384626433832795;
????
private?const?double?PI2?=?6.283185307179586476925286766559;

????
///?<summary>
????
///?正弦曲線Wave扭曲圖片(Edit?By?51aspx.com)
????
///?</summary>
????
///?<param?name="srcBmp">圖片路徑</param>
????
///?<param?name="bXDir">如果扭曲則選擇為True</param>
????
///?<param?name="nMultValue">波形的幅度倍數,越大扭曲的程度越高,一般為3</param>
????
///?<param?name="dPhase">波形的起始相位,取值區間[0-2*PI)</param>
????
///?<returns></returns>
????public?System.Drawing.Bitmap?TwistImage(Bitmap?srcBmp,?bool?bXDir,?double?dMultValue,?double?dPhase)
????{
????????System.Drawing.Bitmap?destBmp?
=?new?Bitmap(srcBmp.Width,?srcBmp.Height);

????????
//?將位圖背景填充為白色
????????System.Drawing.Graphics?graph?=?System.Drawing.Graphics.FromImage(destBmp);
????????graph.FillRectangle(
new?SolidBrush(System.Drawing.Color.White),?0,?0,?destBmp.Width,?destBmp.Height);
????????graph.Dispose();

????????
double?dBaseAxisLen?=?bXDir???(double)destBmp.Height?:?(double)destBmp.Width;

????????
for?(int?i?=?0;?i?<?destBmp.Width;?i++)
????????{
????????????
for?(int?j?=?0;?j?<?destBmp.Height;?j++)
????????????{
????????????????
double?dx?=?0;
????????????????dx?
=?bXDir???(PI2?*?(double)j)?/?dBaseAxisLen?:?(PI2?*?(double)i)?/?dBaseAxisLen;
????????????????dx?
+=?dPhase;
????????????????
double?dy?=?Math.Sin(dx);

????????????????
//?取得當前點的顏色
????????????????int?nOldX?=?0,?nOldY?=?0;
????????????????nOldX?
=?bXDir???i?+?(int)(dy?*?dMultValue)?:?i;
????????????????nOldY?
=?bXDir???j?:?j?+?(int)(dy?*?dMultValue);

????????????????System.Drawing.Color?color?
=?srcBmp.GetPixel(i,?j);
????????????????
if?(nOldX?>=?0?&&?nOldX?<?destBmp.Width
?????????????????
&&?nOldY?>=?0?&&?nOldY?<?destBmp.Height)
????????????????{
????????????????????destBmp.SetPixel(nOldX,?nOldY,?color);
????????????????}
????????????}
????????}

????????
return?destBmp;
????}



????
#endregion
???
????
///?<summary>
????
///?生成校驗碼圖片
????
///?</summary>
????
///?<param?name="code">驗證碼</param>
????
///?<returns></returns>
????public?Bitmap?CreateImage(string?code)
????{
????????
int?fSize?=?FontSize;
????????
int?fWidth?=?fSize?+?Padding;

????????
int?imageWidth?=?(int)(code.Length?*?fWidth)?+?4?+?Padding?*?2;
????????
int?imageHeight?=?fSize?*?2?+?Padding?*?2;

????????System.Drawing.Bitmap?image?
=?new?System.Drawing.Bitmap(imageWidth,?imageHeight);

????????Graphics?g?
=?Graphics.FromImage(image);

????????g.Clear(BackgroundColor);

????????
//給背景添加隨機生成的燥點
????????if?(this.Chaos)
????????{

????????????Pen?pen?
=?new?Pen(ChaosColor,?0);
????????????
int?c?=?Length?*?10;

????????????
for?(int?i?=?0;?i?<?c;?i++)
????????????{
????????????????
int?x?=?rnd.Next(image.Width);
????????????????
int?y?=?rnd.Next(image.Height);

????????????????g.DrawRectangle(pen,?x,?y,?
1,?1);
????????????}
????????}

????????
int?left?=?0,?top?=?0,?top1?=?1,?top2?=?1;

????????
int?n1?=?(imageHeight?-?FontSize?-?Padding?*?2);
????????
int?n2?=?n1?/?4;
????????top1?
=?n2;
????????top2?
=?n2?*?2;

????????Font?f;
????????Brush?b;

????????
int?cindex,?findex;

????????
//隨機字體和顏色的驗證碼字符
????????for?(int?i?=?0;?i?<?code.Length;?i++)
????????{
????????????cindex?
=?rnd.Next(Colors.Length?-?1);
????????????findex?
=?rnd.Next(Fonts.Length?-?1);

????????????f?
=?new?System.Drawing.Font(Fonts[findex],?fSize,?System.Drawing.FontStyle.Bold);
????????????b?
=?new?System.Drawing.SolidBrush(Colors[cindex]);

????????????
if?(i?%?2?==?1)
????????????{
????????????????top?
=?top2;
????????????}
????????????
else
????????????{
????????????????top?
=?top1;
????????????}

????????????left?
=?i?*?fWidth;

????????????g.DrawString(code.Substring(i,?
1),?f,?b,?left,?top);
????????}

????????
//畫一個邊框?邊框顏色為Color.Gainsboro
????????g.DrawRectangle(new?Pen(Color.Gainsboro,?0),?0,?0,?image.Width?-?1,?image.Height?-?1);
????????g.Dispose();

????????
//產生波形(Add?By?51aspx.com)
????????image?=?TwistImage(image,?true,?8,?4);

????????
return?image;
????}
????????????
????
///?<summary>
????
///?生成隨機字符碼
????
///?</summary>
????
///?<param?name="codeLen">字符串長度</param>
????
///?<param?name="zhCharsCount">中文字符數</param>
????
///?<returns></returns>
????public?string?CreateVerifyCode(int?codeLen,?int?zhCharsCount)
????{
????????
char[]?chs?=?new?char[codeLen];

????????
int?index;
????????
for?(int?i?=?0;?i?<?zhCharsCount;?i++)
????????{
????????????index?
=?rnd.Next(0,?codeLen);
????????????
if?(chs[index]?==?'\0')
????????????????chs[index]?
=?CreateZhChar();
????????????
else
????????????????
--i;
????????}
????????
for?(int?i?=?0;?i?<?codeLen;?i++)
????????{
????????????
if?(chs[i]?==?'\0')
????????????????chs[i]?
=?CreateEnOrNumChar();
????????}

????????
return?new?string(chs,?0,?chs.Length);
????}

????
///?<summary>
????
///?生成默認長度5的隨機字符碼
????
///?</summary>
????
///?<returns></returns>
????public?string?CreateVerifyCode()
????{
????????
return?CreateVerifyCode(Length,?0);
????}
????
????
///?<summary>
????
///?生成英文或數字字符
????
///?</summary>
????
///?<returns></returns>
????protected?char?CreateEnOrNumChar()
????{
????????
return?EnglishOrNumChars[rnd.Next(0,?EnglishOrNumChars.Length)];
????}

????
///?<summary>
????
///?生成漢字字符
????
///?</summary>
????
///?<returns></returns>
????protected?char?CreateZhChar()
????{
????????
//若提供了漢字集,查詢漢字集選取漢字
????????if?(ChineseChars.Length?>?0)
????????{
????????????
return?ChineseChars[rnd.Next(0,?ChineseChars.Length)];
????????}
????????
//若沒有提供漢字集,則根據《GB2312簡體中文編碼表》編碼規則構造漢字
????????else
????????{
????????????
byte[]?bytes?=?new?byte[2];

????????????
//第一個字節值在0xb0,?0xf7之間
????????????bytes[0]?=?(byte)rnd.Next(0xb0,?0xf8);
????????????
//第二個字節值在0xa1,?0xfe之間
????????????bytes[1]?=?(byte)rnd.Next(0xa1,?0xff);

????????????
//根據漢字編碼的字節數組解碼出中文漢字
????????????string?str1?=?Encoding.GetEncoding("gb2312").GetString(bytes);

????????????
return?str1[0];
????????}
????}
}
??? 這里面大量使用了51aspx.com的代碼,在此表示感謝。這里的主要改進在于支持生成中英文混合的驗證碼。中文的生成有兩種方式,一是根據《GB2312簡體中文編碼表》編碼規則構造漢字,二是從一個選定的中文字符集合中隨即選取漢字。實現很簡單,參考函數protected?char?CreateZhChar(),在此不贅述。

??? 最后說一下驗證碼的使用,下面是一個例子:??

<img?src="VerifyCode.aspx"?id="valiCode"?alt="驗證碼"?/>
<a?title="刷新驗證碼"?href="#"?onclick="javascript:document.getElementById('valiCode').src='VerifyCode.aspx?id='+Math.random();return?false;">看不清,換張圖片?</a> ??? 這里有個小技巧,就是在刷新驗證碼的使用,驗證碼的URL后面用了隨機參數以欺騙瀏覽器重新請求。

源代碼
2500常用漢字
498常用漢字

轉載于:https://www.cnblogs.com/homer/archive/2007/12/11/VerifyCode.html

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的[原创]红马版验证码实现(中文+变形+噪点)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。