لقد تلقيت مؤخرًا مهمة في العمل لتطوير وظيفة رمز التحقق من الصفحة، وراجعت بعض المعلومات عبر الإنترنت ودمجت مع معرفتي السابقة في الرسم، وقمت بتنفيذ الحل التالي. يبدو رمز التحقق الذي تم إنشاؤه كما يلي:

المشاكل التي يتعين حلها:
1. كيفية إنشاء صور بشكل عشوائي
لإنشاء كائنات System.Drawing.Bitmap، واستخدام System.Drawing.Graphics للرسم داخل كائنات الصورة النقطية.
2. كيفية تمرير بيانات الصورة من خلال المعلمات في طريقة WebService
لإخراج كائن الصورة النقطية إلى دفق بايت، ويستخدم WebMothod مصفوفة بايت لإرجاع دفق البايت.
مثال:
1. استخدم VS.NET 2003 لإنشاء مشروع ASP.NET Webservice. اسم الخدمة الافتراضي هو MyService، ويتم إضافة WebMethod المسمى GenerateVerifyImage إلى MyService. رمز هذه الطريقة كما يلي:
/// <summary>
/// إنشاء رمز التحقق من الصورة
/// </الملخص>
/// <param name="nLen">طول رمز التحقق</param>
/// <param name="strKey">معلمات الإخراج ومحتوى رمز التحقق</param>
/// <returns>دفق بايت الصورة</returns>
[طريقة ويب]
البايت العام[] GenerateVerifyImage(int nLen,ref string strKey)
{
int nBmpWidth = 13*nLen+5;
int nBmpHeight = 25;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth,nBmpHeight);
// 1. إنشاء لون خلفية عشوائي
int nRed,nGreen,nBlue; // اللون الثلاثي للخلفية
System.Random rd = new Random((int)System.DateTime.Now.Ticks);
nRed = rd.Next(255)%128+128;
nGreen = rd.Next(255)%128+128;
nBlue = rd.Next(255)%128+128;
// 2. املأ الخلفية النقطية
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(nRed,nGreen,nBlue))
,0
,0
،نبمبويدث
,nBmpHeight);
// 3. ارسم خطوط التداخل باستخدام لون أغمق قليلاً من الخلفية
int nLines = 3;
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
ل(int a =0;a< nLines;a++)
{
int x1 = rd.Next() % nBmpWidth;
int y1 = rd.Next() % nBmpHeight;
int x2 = rd.Next() % nBmpWidth;
int y2 = rd.Next() % nBmpHeight;
graph.DrawLine(pen,x1,y1,x2,y2);
}
// يمكن توسيع مجموعة الأحرف المستخدمة في أي وقت ويمكن التحكم في احتمالية ظهور الأحرف
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 4. قم بإجراء حلقة للحصول على الأحرف ورسمها
سلسلة strResult = ""؛
ل(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Next(3));
int y = rd.Next(4) + 1;
// تحديد الخط
خط System.Drawing.Font = جديد System.Drawing.Font("Courier New"،
12 + ثالث.التالي()%4,
System.Drawing.FontStyle.Bold);
char c = strCode[rd.Next(strCode.Length)]; // احصل على أحرف عشوائية
strResult += c.ToString()
;
graph.DrawString(c.ToString(),
الخط,
SolidBrush الجديد (System.Drawing.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)))،
س,
ذ)؛
}
// 5. دفق بايت الإخراج
System.IO.MemoryStream bstream = new System.IO.MemoryStream();
bmp.Save(bstream,System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
graph.Dispose();
strKey = strResult;
byte[] byteReturn = bstream.ToArray();
bstream.Close();
return byteReturn;
}
2. اختبر WebMethod، وأضف WebForm، وراجع خدمة الويب المذكورة أعلاه، واسم المرجع هو Imagesvr. أضف الكود في Page_Load:
...
Imagesvr.MyService imgsvr = new Imagesvr.MyService();
سلسلة strKey = ""؛
byte[] data = imgsvr.GenerateVerifyImage(5,ref strKey);
Response.OutputStream.Write(data,0,data.Length);
...
3. اركض. في كل مرة يتم فيها تحديث WebForm، سيتم عرض رمز التحقق من الصورة الذي تم إنشاؤه حديثًا، وتحفظ معلمة الإخراج strKey للوظيفة المحتوى الفعلي لرمز التحقق، والذي يمكن حفظه في الجلسة للتحقق.
بعد تطوير رمز التحقق من الصورة في المرة الأخيرة، بناءً على اقتراحات بعض الأصدقاء، واستنادًا إلى مبدأ سهولة التعرف على رمز التحقق (للأشخاص)، وصعوبة اختراقه، وجماله، تم تحسين خوارزمية إنشاء رمز التحقق، وتم استخدام طريقة تصفية الصور لتصفية الصور، وتعرض رمز التحقق للتداخل المضاد للتكسير، ومثال الصورة الناتج كما يلي: 
يستخدم تأثير المرشح بشكل أساسي خوارزمية الموجة، التي تنتج تأثير التراكب من خلال معالجة الشكل الموجي الجيبي للمحور X والمحور Y. الوصف الرئيسي للخوارزمية هو كما يلي:
Private const double PI = 3.1415926535897932384626433832795;
const double PI2 = 6.283185307179586476925286766559
/// <summary>
/// صورة مشوهة بالموجة الجيبية
/// </الملخص>
/// <param name="srcBmp"></param>
/// <param name="bXDir"></param>
/// <param name="nMultValue">مضاعفات سعة شكل الموجة</param>
/// <param name="dPhase">مرحلة البداية لشكل الموجة، نطاق القيمة [0-2*PI)</param>
/// <returns></returns>
System.Drawing.Bitmap TwistImage (الصورة النقطية srcBmp، bool bXDir، dMultValue المزدوج، 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();
مزدوج dBaseAxisLen = bXDir ? (مزدوج)destBmp.Height : (مزدوج)destBmp.Width
;
{
ل(int j=0;j<destBmp.Height;j++)
{
مزدوج دكس = 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);
}
}
}
إرجاع destBmp;
}
الصورة النموذجية في البداية هي تراكب تأثيرين على شكل موجة، التأثيران مخصصان لاتجاه المحور X واتجاه المحور Y على التوالي. إذا قمت بإلغاء ملء لون خلفية الحافة، يمكنك رؤية تأثير الخوارزمية على الرسومات، كما هو موضح أدناه: 
يشبه رمز التحقق الذي تم إنشاؤه بهذه الطريقة إلى حد كبير رمز التحقق الموجود على موقع Google، وبالطبع، إذا كنت مهتمًا، فيمكنك أيضًا إضافة تأثيرات مرشح أخرى، مثل التمدد والتدوير والفسيفساء وما إلى ذلك. ولكن يرجى ملاحظة أنه كلما كان رمز التحقق من موقع الويب أكثر تعقيدًا، كان من الأفضل أن تجد التوازن بين السرعة والأمان.