Kürzlich erhielt ich bei der Arbeit die Aufgabe, eine Seitenverifizierungscodefunktion zu entwickeln. Ich habe einige Online-Informationen konsultiert und in Kombination mit meinen bisherigen Zeichenkenntnissen die folgende Lösung implementiert. Der generierte Bestätigungscode sieht folgendermaßen aus:
Zu lösende Probleme:
1. Wie man zufällig Bilder generiert,
um System.Drawing.Bitmap-Objekte zu generieren, und wie man System.Drawing.Graphics verwendet, um in die Bitmap-Objekte zu zeichnen.
2. So übergeben Sie Bilddaten über Parameter in der WebService-Methode,
um das Bitmap-Objekt in einen Byte-Stream auszugeben, und WebMothod verwendet ein Byte-Array, um den Byte-Stream zurückzugeben.
Beispiel:
1. Verwenden Sie VS.NET 2003, um ein ASP.NET-Webservice-Projekt zu erstellen. Der Standarddienstname ist MyService, und eine WebMethod namens GenerateVerifyImage wird zu MyService hinzugefügt. Der Code dieser Methode lautet wie folgt:
/// <summary>
/// Bildverifizierungscode generieren
/// </summary>
/// <param name="nLen">Die Länge des Bestätigungscodes</param>
/// <param name="strKey">Ausgabeparameter, Inhalt des Bestätigungscodes</param>
/// <returns>Bild-Byte-Stream</returns>
[WebMethod]
öffentliches Byte[] 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. Zufällige Hintergrundfarbe generieren
int nRed,nGreen,nBlue; // Die ternäre Farbe des Hintergrunds
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. Füllen Sie den Bitmap-Hintergrund
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(nRed,nGreen,nBlue))
,0
,0
,nBmpWidth
,nBmpHeight);
// 3. Zeichnen Sie Interferenzlinien mit einer etwas dunkleren Farbe als der Hintergrund
int nLines = 3;
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
for(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);
}
// Der verwendete Zeichensatz kann jederzeit erweitert und die Wahrscheinlichkeit des Auftretens von Zeichen gesteuert werden
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 4. Schleife, um Zeichen zu erhalten und zu zeichnen
string strResult = "";
for(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Next(3));
int y = rd.Next(4) + 1;
// Bestimmen Sie die Schriftart
System.Drawing.Font Schriftart = new System.Drawing.Font("Courier New",
12 + rd.Next()%4,
System.Drawing.FontStyle.Bold);
char c = strCode[rd.Next(strCode.Length)]; // Zufällige Zeichen abrufen
strResult += c.ToString();
// Zeichen zeichnen
graph.DrawString(c.ToString(),
Schriftart,
new SolidBrush(System.Drawing.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
X,
y);
}
// 5. Byte-Stream ausgeben
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. Testen Sie die WebMethod, fügen Sie ein WebForm hinzu, verweisen Sie auf den obigen WebService. Der Referenzname lautet imagesvr. Code in Page_Load hinzufügen:
...
imagesvr.MyService imgsvr = new imagesvr.MyService();
string strKey = "";
byte[] data = imgsvr.GenerateVerifyImage(5,ref strKey);
Response.OutputStream.Write(data,0,data.Length);
...
3. Laufen. Jedes Mal, wenn das WebForm aktualisiert wird, wird ein neu generierter Bildbestätigungscode angezeigt. Der Ausgabeparameter strKey der Funktion speichert den tatsächlichen Inhalt des Bestätigungscodes, der zur Überprüfung in der Sitzung gespeichert werden kann.
Nach der letzten Entwicklung des Bildbestätigungscodes wurde der Algorithmus zur Generierung des Bestätigungscodes verbessert, basierend auf den Vorschlägen einiger Freunde, basierend auf dem Prinzip, dass der Bestätigungscode (für Menschen) leicht zu erkennen, schwer zu knacken und schön ist. und die Bildfiltermethode wurde verwendet, um die Bilder zu filtern. Der Verifizierungscode wird einer Anti-Cracking-Interferenz unterzogen, und das Ergebnisbildbeispiel ist wie folgt:
Der Filtereffekt nutzt hauptsächlich den Wellenalgorithmus, der durch Verarbeitung der Sinuswellenform der X-Achse und der Y-Achse einen Überlagerungseffekt erzeugt. Die Hauptbeschreibung des Algorithmus lautet wie folgt:
private const double PI = 3.1415926535897932384626433832795;
private const double PI2 = 6.283185307179586476925286766559
/// <summary>
/// Sinuswelle verzerrtes Bild
/// </summary>
/// <param name="srcBmp"></param>
/// <param name="bXDir"></param>
/// <param name="nMultValue">Amplitudenvielfaches der Wellenform</param>
/// <param name="dPhase">Startphase der Wellenform, Wertebereich [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);
// Den Bitmap-Hintergrund mit Weiß füllen
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++)
{
doppeltes dx = 0;
dx = bXDir ? (PI2*(double)j)/dBaseAxisLen : (PI2*(double)i)/dBaseAxisLen;
dx += dPhase;
double dy = Math.Sin(dx);
// Ermittelt die Farbe des aktuellen Punktes
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;
}
Das Beispielbild am Anfang ist die Überlagerung zweier Wellenformeffekte. Die beiden Effekte gelten jeweils für die X-Achsen-Richtung und die Y-Achsen-Richtung. Wenn Sie die Füllung der Kantenhintergrundfarbe abbrechen, können Sie die Auswirkung sehen Der Algorithmus ist in der Grafik dargestellt, wie unten gezeigt:
Der auf diese Weise generierte Bestätigungscode ähnelt stark dem Bestätigungscode auf der Google-Website. Natürlich können Sie bei Interesse auch andere Filtereffekte wie Dehnung, Drehung, Mosaik usw. hinzufügen. Bitte beachten Sie jedoch, dass Sie ein Gleichgewicht zwischen Geschwindigkeit und Sicherheit finden müssen, je komplexer der Website-Bestätigungscode ist.