Recientemente, recibí una tarea en el trabajo para desarrollar una función de código de verificación de página. Consulté información en línea y, combinado con mis conocimientos previos de dibujo, implementé la siguiente solución. El código de verificación generado se ve así:
Problemas a resolver:
1. Cómo generar imágenes aleatoriamente
para generar objetos System.Drawing.Bitmap y usar System.Drawing.Graphics para dibujar en los objetos de mapa de bits.
2. Cómo pasar datos de imagen a través de parámetros en el método WebService
para generar el objeto Bitmap en un flujo de bytes, y WebMothod usa una matriz de bytes para devolver el flujo de bytes.
Ejemplo:
1. Utilice VS.NET 2003 para crear un proyecto de servicio web ASP.NET. El nombre del servicio predeterminado es MyService y se agrega un método web llamado GenerateVerifyImage a MyService. El código de este método es el siguiente:
/// <resumen>
/// Generar código de verificación de imagen
/// </summary>
/// <param name="nLen">La longitud del código de verificación</param>
/// <param name="strKey">Parámetros de salida, contenido del código de verificación</param>
/// <returns>Flujo de bytes de imagen</returns>
[Método web]
byte público [] GenerateVerifyImage (int nLen, cadena de referencia strKey)
{
int nBmpWidth = 13*nLen+5;
int nBmpHeight = 25;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth,nBmpHeight
// 1. Generar color de fondo aleatorio
);
int nRed,nGreen,nBlue; // El color ternario del fondo.
System.Random rd = nuevo Random((int)System.DateTime.Now.Ticks);
nRojo = rd.Siguiente(255)%128+128;
nVerde = rd.Siguiente(255)%128+128;
nBlue = rd.Next(255)%128+128
// 2. Rellena el fondo del mapa de bits
System.Drawing.Graphics gráfico = System.Drawing.Graphics.FromImage(bmp);
graph.FillRectangle(nuevo SolidBrush(System.Drawing.Color.FromArgb(nRed,nGreen,nBlue))
,0
,0
,nBmpAncho
,nBmpAltura);
// 3. Dibuja líneas de interferencia, usando un color ligeramente más oscuro que el fondo.
int nLíneas = 3;
System.Drawing.Pen pluma = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed-17,nGreen-17,nBlue-17),2);
para(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;
gráfico.DrawLine(pluma,x1,y1,x2,y2);
}
// El conjunto de caracteres utilizado se puede ampliar en cualquier momento y se puede controlar la probabilidad de que aparezcan caracteres
string strCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
// 4. Bucle para obtener caracteres y dibujarlos
cadena strResult = "";
para(int i=0;i<nLen;i++)
{
int x = (i*13 + rd.Siguiente(3));
int y = rd.Next(4) + 1
// Determinar la fuente
System.Drawing.Font fuente = nuevo System.Drawing.Font("Courier New",
12 + rd.Siguiente()%4,
Sistema.Dibujo.FontStyle.Bold);
char c = strCode[rd.Next(strCode.Length)] // Obtener caracteres aleatorios
strResult += c.ToString();
// Dibujar caracteres
gráfico.DrawString(c.ToString(),
fuente,
nuevo SolidBrush(System.Drawing.Color.FromArgb(nRed-60+y*3,nGreen-60+y*3,nBlue-40+y*3)),
incógnita,
y);
}
// 5. Flujo de bytes de salida
System.IO.MemoryStream bstream = nuevo System.IO.MemoryStream();
bmp.Save(bstream,System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose();
graph.Dispose();
strKey = strResult;
byte[] byteReturn = bstream.ToArray();
bstream.Close();
devolver byteReturn;
}
2. Pruebe el WebMethod, agregue un WebForm, haga referencia al WebService anterior y el nombre de referencia es imagesvr. Agregar código en Page_Load:
...
imágenesvr.MyService imgsvr = nuevas imágenesvr.MyService();
cadena strKey = "";
byte[] datos = imgsvr.GenerateVerifyImage(5,ref strKey);
Response.OutputStream.Write(datos,0,datos.Longitud);
...
3. Corre. Cada vez que se actualiza el WebForm, se mostrará un código de verificación de imagen recién generado y el parámetro de salida strKey de la función guarda el contenido real del código de verificación, que se puede guardar en la sesión para su verificación.
Después de desarrollar el código de verificación de imagen la última vez, según las sugerencias de algunos amigos, basándose en el principio de que el código de verificación es fácil de reconocer (para las personas), difícil de descifrar y hermoso, se ha mejorado el algoritmo de generación del código de verificación. y se ha utilizado el método de filtro de imagen para filtrar las imágenes. El código de verificación se somete a interferencias anti-craqueo y el ejemplo de imagen resultante es el siguiente:
El efecto de filtro utiliza principalmente el algoritmo de onda, que produce un efecto de superposición al procesar la forma de onda sinusoidal de los ejes X e Y. La descripción principal del algoritmo es la siguiente:
const privada doble PI = 3.1415926535897932384626433832795;
const privada doble PI2 = 6.283185307179586476925286766559
/// <resumen>
/// Imagen distorsionada de onda sinusoidal
/// </summary>
/// <param nombre="srcBmp"></param>
/// <param nombre="bXDir"></param>
/// <param name="nMultValue">Amplitud múltiplo de la forma de onda</param>
/// <param name="dPhase">Fase inicial de la forma de onda, rango de valores [0-2*PI)</param>
/// <devoluciones></devoluciones>
sistema público.Drawing.Bitmap TwistImage (mapa de bits srcBmp, bool bXDir, doble dMultValue, doble dPhase)
{
System.Drawing.Bitmap destBmp = new Bitmap(srcBmp.Width,srcBmp.Height
// Rellena el fondo del mapa de bits con blanco
);
System.Drawing.Graphics gráfico = System.Drawing.Graphics.FromImage(destBmp);
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White),0,0,destBmp.Width,destBmp.Height);
gráfico.Dispose();
doble dBaseAxisLen = bXDir ? (doble)destBmp.Height : (doble)destBmp.Width
para(int i=0;i<destBmp.Width;i++)
{
for(int j=0;j<destBmp.Height;j++)
{
doble dx = 0;
dx = bXDir ? (PI2*(doble)j)/dBaseAxisLen : (PI2*(doble)i)/dBaseAxisLen;
dx += dFase;
double dy = Math.Sin(dx);
// Obtiene el color del punto actual
int nViejoX = 0,nViejoY = 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.Ancho
&& nOldY >=0 && nOldY < destinoBmp.Altura)
{
destBmp.SetPixel(nOldX,nOldY,color);
}
}
}
devolver destinoBmp;
}
La imagen de ejemplo al principio es la superposición de dos efectos de forma de onda. Los dos efectos son para la dirección del eje X y la dirección del eje Y respectivamente. Si cancela el relleno del color de fondo del borde, puede ver el impacto. el algoritmo en los gráficos, como se muestra a continuación:
El código de verificación generado de esta manera se parece mucho al código de verificación del sitio de Google. Por supuesto, si está interesado, también puede agregar otros efectos de filtro, como estiramiento, rotación, mosaico, etc. Pero tenga en cuenta que cuanto más complejo sea el código de verificación del sitio web, mejor deberá encontrar un equilibrio entre velocidad y seguridad.