elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [SOURCE] Generar captchas para aplicaciones
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [SOURCE] Generar captchas para aplicaciones  (Leído 2,475 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
[SOURCE] Generar captchas para aplicaciones
« en: 15 Diciembre 2015, 13:24 pm »

Buenas

Os dejo este sencillo y pequeño algoritmo para generar captchas para nuestras aplicaciones.

Se puede extender para añadir "ruido" en la imagen, o alterar la posición y la rotación de las letras, pero eso no lo he implementado ya que me parece algo excesivo para "autentificar" una simple aplicación de escritorio.

       
 
Modo de empleo:
Código
  1. Dim captcha As KeyValuePair(Of Bitmap, String) = GenerateCaptcha(length:=5, size:=PictureBox1.Size)
  2.  
  3. PictureBox1.BackgroundImage = captcha.Key
  4. Console.WriteLine(captcha.Value)

Código fuente:
Código
  1.    Dim rand As New Random
  2.  
  3.    ''' ----------------------------------------------------------------------------------------------------
  4.    ''' <summary>
  5.    ''' Generates a captcha image.
  6.    ''' </summary>
  7.    ''' ----------------------------------------------------------------------------------------------------
  8.    ''' <example> This is a code example.
  9.    ''' <code>
  10.    ''' Dim captcha As KeyValuePair(Of Bitmap, String) = GenerateCaptcha(5, PictureBox1.ClientSize)
  11.    ''' PictureBox1.BackgroundImage = captcha.Key
  12.    ''' </code>
  13.    ''' </example>
  14.    ''' ----------------------------------------------------------------------------------------------------
  15.    ''' <param name="length">
  16.    ''' The character length.
  17.    ''' </param>
  18.    '''
  19.    ''' <param name="size">
  20.    ''' The image size.
  21.    ''' </param>
  22.    ''' ----------------------------------------------------------------------------------------------------
  23.    ''' <returns>
  24.    ''' A <see cref="KeyValuePair(Of Bitmap, String)"/> that contains the captcha image and the resulting string.
  25.    ''' </returns>
  26.    ''' ----------------------------------------------------------------------------------------------------
  27.    <DebuggerStepThrough>
  28.    Public Shared Function GenerateCaptcha(ByVal length As Integer,
  29.                                           ByVal size As Size) As KeyValuePair(Of Bitmap, String)
  30.  
  31.        Return GenerateCaptcha(length, size.Width, size.Height)
  32.  
  33.    End Function
  34.  
  35.    ''' ----------------------------------------------------------------------------------------------------
  36.    ''' <summary>
  37.    ''' Generates a captcha image.
  38.    ''' </summary>
  39.    ''' ----------------------------------------------------------------------------------------------------
  40.    ''' <example> This is a code example.
  41.    ''' <code>
  42.    ''' Dim captcha As KeyValuePair(Of Bitmap, String) = GenerateCaptcha(5, PictureBox1.Width, PictureBox1.Height)
  43.    ''' PictureBox1.BackgroundImage = captcha.Key
  44.    ''' </code>
  45.    ''' </example>
  46.    ''' ----------------------------------------------------------------------------------------------------
  47.    ''' <param name="length">
  48.    ''' The character length.
  49.    ''' </param>
  50.    '''
  51.    ''' <param name="width">
  52.    ''' The image width.
  53.    ''' </param>
  54.    '''
  55.    ''' <param name="height">
  56.    ''' The image height.
  57.    ''' </param>
  58.    ''' ----------------------------------------------------------------------------------------------------
  59.    ''' <returns>
  60.    ''' A <see cref="KeyValuePair(Of Bitmap, String)"/> that contains the captcha image and the resulting string.
  61.    ''' </returns>
  62.    ''' ----------------------------------------------------------------------------------------------------
  63.    <DebuggerStepThrough>
  64.    Public Shared Function GenerateCaptcha(ByVal length As Integer,
  65.                                           ByVal width As Integer,
  66.                                           ByVal height As Integer) As KeyValuePair(Of Bitmap, String)
  67.  
  68.        Dim captcha As New Bitmap(width, height)
  69.        Dim fontHeight As Integer = (height \ 2)
  70.        Dim vLineSpacing As Integer = 2
  71.        Dim hLineSpacing As Integer = 2
  72.        Dim str As String = String.Join("", (From c As Char In "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  73.                                     Order By rand.Next Select c).Take(length))
  74.  
  75.        Using g As Graphics = Graphics.FromImage(captcha)
  76.  
  77.            g.InterpolationMode = InterpolationMode.High
  78.            g.SmoothingMode = SmoothingMode.HighQuality
  79.            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
  80.            g.CompositingQuality = CompositingQuality.HighQuality
  81.  
  82.            Using gradientBrush As New LinearGradientBrush(New Point(0, (height \ 2)),
  83.                                                           New Point(width, (height \ 2)),
  84.                                                           Color.FromArgb(rand.Next(&HFF7D7D7D, &HFFFFFFFF)),
  85.                                                           Color.FromArgb(rand.Next(&HFF7D7D7D, &HFFFFFFFF)))
  86.  
  87.                ' Draw gradient background.
  88.                g.FillRectangle(gradientBrush, New Rectangle(0, 0, width, height))
  89.  
  90.            End Using ' gradientBrush
  91.  
  92.            Using linesPen As New Pen(Brushes.Black, 1)
  93.  
  94.                ' Draw vertical lines.
  95.                For i As Integer = 1 To width
  96.                    Dim ptop As New Point(i * vLineSpacing, 0)
  97.                    Dim pBottom As New Point(i * vLineSpacing, height)
  98.                    g.DrawLine(linesPen, ptop, pBottom)
  99.                Next i
  100.  
  101.                ' Draw horizontal lines.
  102.                For i As Integer = 1 To height
  103.                    Dim ptop As New Point(0, i * hLineSpacing)
  104.                    Dim pBottom As New Point(width, i * hLineSpacing)
  105.                    g.DrawLine(linesPen, ptop, pBottom)
  106.                Next i
  107.  
  108.            End Using ' linesPen
  109.  
  110.            Using font As New Font("Arial", fontHeight)
  111.  
  112.                Using path As New GraphicsPath
  113.  
  114.                    For i As Integer = 0 To (str.Length - 1)
  115.  
  116.                        Dim charX As Integer =
  117.                            (((i * (width - (g.MeasureString(str(i), font, width).ToSize.Width \ length)))) \ length)
  118.  
  119.                        Dim charY As Integer = (height \ 2)
  120.  
  121.                        path.AddString(str(i), font.FontFamily, FontStyle.Bold, fontHeight,
  122.                                       New Point(charX, charY), New StringFormat With {.LineAlignment = StringAlignment.Center})
  123.  
  124.                    Next i
  125.  
  126.                    ' Draw characters.
  127.                    g.DrawPath(Pens.Black, path)
  128.                    g.FillPath(Brushes.Gainsboro, path)
  129.  
  130.                End Using
  131.  
  132.            End Using ' font
  133.  
  134.        End Using ' g
  135.  
  136.        Return New KeyValuePair(Of Bitmap, String)(captcha, str)
  137.  
  138.    End Function

Saludos


« Última modificación: 15 Diciembre 2015, 13:28 pm por Eleкtro » En línea



kub0x
Enlightenment Seeker
Moderador
***
Desconectado Desconectado

Mensajes: 1.486


S3C M4NI4C


Ver Perfil
Re: [SOURCE] Generar captchas para aplicaciones
« Respuesta #1 en: 21 Diciembre 2015, 14:15 pm »

Simple y sencillo, se ve estupéndamente EleKtro, como curiosidad, ¿has probado a pasarle OCR?

Saludos!


En línea

Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.866



Ver Perfil
Re: [SOURCE] Generar captchas para aplicaciones
« Respuesta #2 en: 21 Diciembre 2015, 19:38 pm »

Simple y sencillo, se ve estupéndamente EleKtro, como curiosidad, ¿has probado a pasarle OCR?

Segurísimo que cualquier motor OCR leería perfectamente las letras, ni falta que hace probarlo creo yo, ya que no implementé medidas de seguridad por así decirlo, vaya.

El propósito del código que compartí era mostrar las letras lo más legible posible para el usuario, sin sobrecargar la imagen, ya que considero que una aplicación no necesita más.

Aquí les dejo una versión alternativa para mostrar maneras de extender el código, con fuentes de letra aleatorias, posición de letras aleatoria, curvas y ruido,
aunque no me gusta como ha quedado el resultado, se podría hacer mucho mejor pero no soy ningún gurú del GDI+ y no invertiré más tiempo en ello, ya que como dije, no quería sobrecargar la imagen.

     

     

Código
  1.    Private Shared rand As New Random
  2.  
  3.    Public Shared Function GenerateCaptcha(ByVal length As Integer,
  4.                                           ByVal width As Integer,
  5.                                           ByVal height As Integer) As KeyValuePair(Of Bitmap, String)
  6.  
  7.        Dim vLinesGdi As New Dictionary(Of Point, Point)
  8.        Dim hLinesGdi As New Dictionary(Of Point, Point)
  9.        Dim charsGdi As New Dictionary(Of Char, Point)
  10.        Dim captcha As New Bitmap(width, height)
  11.        Dim fontHeight As Integer = (height \ 2)
  12.        Dim vLineSpacing As Integer = 2
  13.        Dim hLineSpacing As Integer = 2
  14.        Dim str As String =
  15.            String.Join("", (From c As Char In "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  16.                             Order By rand.Next Select c).Take(length))
  17.  
  18.        ' Set vertical lines.
  19.        For i As Integer = 1 To width
  20.            vLinesGdi.Add(New Point(i * vLineSpacing, 0), New Point(i * vLineSpacing, height))
  21.        Next i
  22.  
  23.        ' Set horizontal lines.
  24.        For i As Integer = 1 To height
  25.            hLinesGdi.Add(New Point(0, i * hLineSpacing), New Point(width, i * hLineSpacing))
  26.        Next i
  27.  
  28.        ' Set char positions.
  29.        Using g As Graphics = Graphics.FromImage(captcha)
  30.  
  31.            For i As Integer = 0 To (length - 1)
  32.  
  33.                Using font As New Font(GetRandomFont, fontHeight)
  34.  
  35.                    Dim charPosX As Integer =
  36.                        (((i * (width - (g.MeasureString(str(i), font, width).ToSize.Width \ length)))) \ length)
  37.  
  38.                    Dim charPosY As Integer = rand.Next((fontHeight \ 2), height - (fontHeight \ 2))
  39.  
  40.                    charsGdi.Add(str(i), New Point(charPosX, charPosY))
  41.  
  42.                End Using ' font
  43.  
  44.            Next
  45.  
  46.        End Using ' g
  47.  
  48.        Using g As Graphics = Graphics.FromImage(captcha)
  49.  
  50.            g.InterpolationMode = InterpolationMode.HighQualityBicubic
  51.            g.SmoothingMode = SmoothingMode.HighQuality
  52.            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
  53.            g.CompositingQuality = CompositingQuality.GammaCorrected
  54.            g.PixelOffsetMode = PixelOffsetMode.HighQuality
  55.  
  56.            ' Draw background.
  57.            Using bgBrush As New LinearGradientBrush(New Point(0, (height \ 2)),
  58.                                                     New Point(width, (height \ 2)),
  59.                                                     Color.FromArgb(rand.Next(&HFF7D7D7D, &HFFFFFFFF)),
  60.                                                     Color.FromArgb(rand.Next(&HFF7D7D7D, &HFFFFFFFF)))
  61.  
  62.                g.FillRectangle(bgBrush, New Rectangle(0, 0, width, height))
  63.            End Using ' bgBrush
  64.  
  65.            ' Draw rectangles.
  66.            Using linePen As New Pen(Brushes.Gray, 1)
  67.  
  68.                ' Draw vertical rect-lines.
  69.                For Each linePair As KeyValuePair(Of Point, Point) In vLinesGdi
  70.                    g.DrawLine(linePen, linePair.Key, linePair.Value)
  71.                Next linePair
  72.  
  73.                ' Draw horizontal rect-lines.
  74.                For Each linePair As KeyValuePair(Of Point, Point) In hLinesGdi
  75.                    g.DrawLine(linePen, linePair.Key, linePair.Value)
  76.                Next linePair
  77.  
  78.            End Using ' linePen
  79.  
  80.            ' Draw characters.
  81.            For Each charPoint As KeyValuePair(Of Char, Point) In charsGdi
  82.  
  83.                Using font As New Font(GetRandomFont, fontHeight)
  84.  
  85.                    Using path As New GraphicsPath
  86.  
  87.                        path.FillMode = FillMode.Alternate
  88.                        path.AddString(charPoint.Key, font.FontFamily, FontStyle.Bold, fontHeight,
  89.                                       New Point(charPoint.Value.X, charPoint.Value.Y),
  90.                                       New StringFormat With {
  91.                                           .Alignment = StringAlignment.Near,
  92.                                           .LineAlignment = StringAlignment.Center,
  93.                                           .FormatFlags = StringFormatFlags.NoFontFallback Or StringFormatFlags.NoWrap
  94.                                       })
  95.  
  96.                        g.DrawPath(Pens.Black, path)
  97.                        g.FillPath(Brushes.Gainsboro, path)
  98.  
  99.                    End Using ' path
  100.  
  101.                End Using ' font
  102.  
  103.            Next charPoint
  104.  
  105.            ' Draw curve.
  106.            Using curvePen As New Pen(Brushes.Black, 1.5F)
  107.                g.DrawCurve(curvePen, charsGdi.Values.ToArray, 0, (length - 1), 10.0F)
  108.            End Using ' curvePen
  109.  
  110.            '' Add noise.
  111.            '' Nota: Usar "Bitmap.Lockbits()" para quien quiera una implementación más rápida y eficiente.
  112.            'For x As Integer = 0 To (width - 1) Step 6
  113.            '    For y As Integer = 0 To (height - 1) Step 6
  114.            '        Dim num As Integer = rand.Next(0, 256)
  115.            '        captcha.SetPixel(x, y, Color.FromArgb(255, num, num, num))
  116.            '    Next
  117.            'Next
  118.  
  119.        End Using ' g
  120.  
  121.        Return New KeyValuePair(Of Bitmap, String)(captcha, str)
  122.  
  123.    End Function
  124.  
  125.    Public Shared Function GetRandomFont() As FontFamily
  126.  
  127.        Using fontCol As New InstalledFontCollection
  128.            Return (From family As FontFamily In fontCol.Families
  129.                    Order By rand.Next Select family).First
  130.        End Using
  131.  
  132.    End Function

Notas:
No lo he probado con un OCR.
El código es solo un ejemplo, una base donde agarrarse.
Conviene usar una colección de fuentes óptima y personalizada, para evitar fuentes de texto incompletas y/o simbólicas como la fuente Widenings de Microsoft.

Saludos!
« Última modificación: 21 Diciembre 2015, 20:24 pm por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines