Derrota SVGCaptcha

79

Encontré SVGCaptcha , e inmediatamente supe que era una mala idea.

Me gustaría que mostrara cuán mala es esta idea extrayendo el código de validación de las imágenes SVG que produce el código.


Una imagen de ejemplo se ve así: Aquí está la fuente de la imagen de ejemplo:
8u4x8lf

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
        "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
             width="200" height="40"
    > <rect x="0" y="0" width="200" height="40" 
        style="stroke: none; fill: none;" >
        </rect> <text style="fill: #4d9363;" x="5" y="34" font-size="20" transform="translate(5, 34) rotate(-17) translate(-5, -34)">8</text>
<text style="fill: #be8b33;" x="125" y="29" font-size="21" transform="translate(125, 29) rotate(17) translate(-125, -29)">f</text>
<text style="fill: #d561ff;" x="45" y="35" font-size="20" transform="translate(45, 35) rotate(-2) translate(-45, -35)">4</text>
<text style="fill: #3de754;" x="85" y="31" font-size="21" transform="translate(85, 31) rotate(-9) translate(-85, -31)">8</text>
<text style="fill: #5ed4bf;" x="25" y="33" font-size="22" transform="translate(25, 33) rotate(16) translate(-25, -33)">u</text>
<text style="fill: #894aee;" x="105" y="28" font-size="25" transform="translate(105, 28) rotate(9) translate(-105, -28)">1</text>
<text style="fill: #e4c437;" x="65" y="32" font-size="20" transform="translate(65, 32) rotate(17) translate(-65, -32)">x</text>
</svg>

La entrada es la imagen SVG, que es un formato de texto.

La única restricción real es que su código debe producir los valores en el orden correcto .
Los <text>elementos de entrada están en orden aleatorio, por lo que debe prestar atención al xatributo en la <text>etiqueta


El puntaje es el número de bytes en el código


Dado que el código actualmente realiza dos transformaciones que se cancelan entre sí, puede ignorarlas, pero si las toma en consideración, continúe y obtenga una reducción del 30% de su puntaje.

Brad Gilbert b2gills
fuente
3
En realidad, no ha declarado explícitamente cuáles son las entradas y salidas: ¿Estoy suponiendo que el archivo SVG y las letras que contiene? Y no está claro para mí si se requieren respuestas para implementar realmente la especificación SVG o si pueden suponer que el SVG es generado por la versión actual de SVGCaptcha y, por lo tanto, las transformaciones pueden ignorarse.
Peter Taylor
Sugiero limitar la salida a STDOUT o el valor de retorno de la función, y hacerlo code-golf
TheDoctor
1
No, las preguntas necesitan un criterio ganador cuantificable objetivo para estar en el tema de este sitio.
Alex A.
77
No estoy seguro de cuán relevante es el procesamiento de imágenes aquí.
SuperJedi224
18
Esta pregunta es ahora el cuarto resultado cuando buscas en Google 'svgcaptcha' :)
Azul

Respuestas:

18

Bash , 63 56 39 bytes

cat<<_|grep -o 'x=.*>'|cut -c4-|sort -n|grep -o '>.</t'|cut -c2

grep -o 'x=.*>'|cut -c4-|sort -n|grep -o '>.</t'|cut -c2

grep -o 'x=.*<'|sort -k1.4n|rev|cut -c2

Nota: requiere cat, grep , sort, rev, y cut. Toma información de stdin. La salida está separada por saltos de línea en stdout. Asegúrese de presionar CTRL + D (no COMMAND + D en Mac) cuando termine de ingresar el CAPTCHA. La entrada debe ir seguida de una nueva línea y luego '_'.

EDITAR : guardado 13 bytes.

EDIT 2 : ¡ Ahorró 20 bytes gracias a @manatwork !

Codificador256
fuente
GNU coreutils sort admite la posición de los caracteres en el keydef: cut -c4-|sort -nsort -k1.4n.
manatwork
@manatwork Gracias, actualicé la respuesta.
Coder256
13

CJam, 26 bytes

q"x="/2>{'"/1=i}${'>/1=c}/

Pruébelo en línea en el intérprete de CJam .

Cómo funciona

q     e# Read all input from STDIN.
"x="/ e# Split it at occurrences of "x=".
2>    e# Discard the first two chunks (head and container).
{     e# Sort the remaining chunks by the following key:
  '"/ e#   Split at occurrences of '"'.
  1=  e#   Select the second chunk (digits of x="<digits>").
  i   e#   Cast to integer.
}$    e#
{     e# For each of the sorted chunks:
  '>/ e#   Split at occurrences of '>'.
  1=  e#   Select the second chunk.
  c   e#   Cast to character.
}/    e#
Dennis
fuente
8

JavaScript, 95 93 91 bytes

l=[],r=/x="(\d*).*>(.)/g;while(e=r.exec(document.lastChild.innerHTML))l[e[1]]=e[2];l.join``

editar: -2 bytes cambiando documentRoota lastChild; -2 bytes cambiando join('')a join``, gracias Vɪʜᴀɴ

Ingrese el código en la consola del navegador en una página que contenga el SVG en cuestión, escribe en la salida de la consola.

Nickson
fuente
document.rootElementestá reajustando indefinido. He probado Firefox y Safari
Downgoat el
Esto solo se probó en Chrome, analizaré qué podría cambiarse.
Nickson
Parece funcionar en Firefox, ¿es SVG el único contenido del archivo?
Nickson
Bien, lo probé en Chrome, ahora funcionó. +1. También puede guardar dos bytes cambiando los ('')dos backticks: ``
Downgoat
Esto es 78: t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))(toma la cadena xml como parámetro, devuelve texto captcha)
DankMemes
7

Perl, 40 bytes

Código de 39 bytes + 1 para -n

$a[$1]=$2 for/x="(.+)".+(.)</g}{print@a

Ejemplo:

perl -ne '$a[$1]=$2 for/x="(.+)".+(.)</g}{print@a' <<< '<example from above>'
8u4x81f
Dom Hastings
fuente
Hombre que está lleno de advertencias si las enciendes. Excelente uso de la naturaleza laxa por defecto de Perl.
Brad Gilbert b2gills
@ BradGilbertb2gills Sí, trato de no probar las advertencias, ¡estoy tan sorprendido de que algún código de golf incluso funcione a veces!
Dom Hastings
7

Bash + utilidades GNU, 53

grep -Po '(?<=x=").*(?=<)'|sort -n|grep -Po '(?<=>).'

Al igual que esta respuesta , la salida es un carácter por línea.

Trauma digital
fuente
3

Perl 6 , 68 bytes

say [~] lines.map({/'x="'(\d+).*(.)\</??(+$0=>$1)!!()}).sort».value
Brad Gilbert b2gills
fuente
3

Befunge, 79 bytes

Parece que debería ser posible jugar al menos un byte más de esto, pero he estado trabajando en ello durante un par de días, y esto es lo mejor que pude obtener.

<%*:"~"*"~"_~&45*/99p1v-">":_|#`0:~<
#,:#g7-#:_@^-+*"x~=":+_~99g7p>999p#^_>>#1+

Pruébalo en línea!

Explicación

Código fuente con rutas de ejecución resaltadas

* *Haga la dirección de ejecución de derecha a izquierda y ajuste para iniciar el bucle principal.
* *Lea un char de stdin y pruebe el valor de fin de archivo.
* *Si no es el final del archivo, verifique si es un >.
* *Si no es un >, agrégalo al valor en la pila que rastrea los últimos dos caracteres y verifica si el par actual coincide x=.
* *Si no, multiplíquelo por 126 y modifique por 126 2 para eliminar el valor más antiguo del par y dejar espacio para el siguiente personaje.
* *Envuelva nuevamente para repetir el bucle principal.
* *Cuando x=se encuentra un par, omita el siguiente carácter (la cita), lea un número entero (el valor x ) y divida por 20. Esto se convierte en el desplazamiento actual que se guarda para más adelante.
* *Cuando >se encuentra un, lea el siguiente carácter (generalmente una de las letras captcha) y guárdelo en el desplazamiento actual en una "matriz". Restablezca el desplazamiento a 9, por lo que la letra captcha no se sobrescribirá cuando >se encuentren caracteres posteriores .
* *Finalmente, cuando se alcanza el final del archivo, repita los 7 valores guardados en la matriz y expórtelos uno por uno. Eso debería darte todas las letras captcha en el orden correcto.

Estoy pasando por alto algunos de los detalles aquí, ya que las rutas de código se superponen entre sí de maneras que son un poco difíciles de explicar, pero debería darle una idea general de cómo funciona el algoritmo.

James Holderness
fuente
2

Python2, 129 bytes

import re,sys
print''.join(t[1] for t in sorted(re.findall(r'(\d+), -\d+\)"\>(.)\</t',sys.stdin.read()),key=lambda t:int(t[0])))

Toma la fuente HTML en stdin, produce código en stdout.

orlp
fuente
¿Cómo ordena esto la salida? Los <text>elementos están en un orden aleatorio, y el único requisito real es que debe colocarlos en el orden correcto. Eso significa que tienes que usar xdesde <text>y seguir cualquier transformación.
Brad Gilbert b2gills
@ BradGilbertb2gills Me perdí eso la primera vez, arreglado ahora.
orlp
2

Mathematica, 106 bytes

""<>(v=ImportString[#~StringDrop~157,"XML"][[2,3,4;;;;2]])[[;;,3]][[Ordering[FromDigits/@v[[;;,2,2,2]]]]]&

Nota: La entrada debe estar exactamente en el formato especificado por el ejemplo.

LegionMammal978
fuente
2

V , 28 26 25 24 bytes

d5j́x=
ún
J́">
lH$dÍî

Pruébalo en línea!

Explicación:

d5j              delete first 6 lines
   Í<0x81>x=     In every line, replace everything up to x=" (inclusive) by nothing
ún               Sort numerically
J                Join line (closing </svg>) with next line
 Í<0x81>">       In every line, replace everything up to "> by nothing
l␖H$d            Visual block around closing </text> tags, delete
     Íî          In every line, replace \n by nothing.

HexDump:

00000000: 6435 6acd 8178 3d0a fa6e 0a4a cd81 223e  d5j..x=..n.J..">
00000010: 0a6c 1648 2464 cdee                      .l.H$d..
oktupol
fuente
2

QuadS , 49 bytes

c[⍋⊃x c←↓⍎¨@1⍉(⊢⍴⍨2,⍨.5×≢)3↓⍵]
x="(\d+)
>(.)<
\1

Pruébalo en línea!

Encuentra los valores de x (dígitos que se ejecutan después x=") y las "letras" (fijadas al cerrar y abrir etiquetas), luego ejecuta el siguiente APL (donde está la lista de valores y letras de x encontrados, en orden de aparición):

3↓⍵ suelte los primeros tres elementos (espacios alrededor de <rect... /rect>y el <rectvalor 'sx).

(... ) aplique la siguiente función tácita sobre eso:

 la cantidad de artículos restantes

.5× reducir a la mitad eso

2,⍨ agregue un dos

⊢⍴⍨ remodelar a esa forma (es decir, una matriz n × 2)

 transposición (a una matriz 2 × n)

⍎¨@1 ejecutar cada cadena en la primera fila (convirtiéndolas en números)

 dividir la matriz en dos vectores (uno por fila)

x c← almacenar esos dos en x (valores x) yc (caracteres) respectivamente

 elige el primero (x)

 subir de grado (los índices en x que ordenarían x)

c[... ] usa eso para indexar enc

ε nlist (aplanar), ya que cada letra es una cadena por sí mismo


La expresión APL equivalente de todo el programa QuadS es:

c[⍋⊃x c←↓⍎¨@1⍉(⊢⍴⍨2,⍨.5×≢)3'x="(\d+)"' '>(.)<'S'\1'⊢⎕]
Adán
fuente
1

Java 8, 197173 bytes

import java.util*;s->{String a[]=s.split("x=\""),r="";Map m=new TreeMap();for(int i=2;i<a.length;m.put(new Long(a[i].split("\"")[0]),a[i++].split(">|<")[1]));return m.values();}

Emite una java.util.Collectionde caracteres.

Explicación:

Pruébalo en línea.

import java.util*;            // Required import for Map and TreeMap
s->{                          // Method with String as both parameter and return-type
  String a[]=s.split("x=\""), //  Split the input by `x="`, and store it as String-array
         r="";                //  Result-String, starting empty
  Map m=new TreeMap();        //  Create a sorted key-value map
  for(int i=2;                //  Skip the first two items in the array,
      i<a.length;             //  and loop over the rest
    m.put(new Long(a[i].split("\"")[0]),
                              //   Split by `"` and use the first item as number-key
          a[i++].split(">|<")[1]));
                              //   Split by `>` AND `<`, and use the second item as value
    return m.values();}       //  Return the values of the sorted map as result
Kevin Cruijssen
fuente
1

Gema , 65 personajes

x\="<D>*\>?=@set{$1;?}
?=
\Z=${5}${25}${45}${65}${85}${105}${125}

En Gema no hay clasificación, pero afortunadamente ni siquiera es necesaria.

Ejecución de muestra:

bash-4.4$ gema 'x\="<D>*\>?=@set{$1;?};?=;\Z=${5}${25}${45}${65}${85}${105}${125}' < captcha.svg
8u4x81f
hombre trabajando
fuente
1

XMLStarlet , 46 caracteres

xmlstarlet sel -t -m //_:text -s A:N:U @x -v .

Esperemos que esta sea una solución válida, ya que XMLStarlet es un transpilador que genera y ejecuta código XSLT, que es un lenguaje completo de Turing.

Ejecución de muestra:

bash-4.4$ xmlstarlet sel -t -m //_:text -s A:N:U @x -v . < captcha.svg 
8u4x81f
hombre trabajando
fuente
1

PHP, 96 bytes

Dado que $ies la cadena de entrada

preg_match_all('|x="(\d+).*(.)\<|',$i,$m);$a=array_combine($m[1],$m[2]);ksort($a);echo join($a);
Jordi Kroon
fuente
1
En lugar de array_combine()+ ksort()se puede utilizar array_multisort()la siguiente manera: array_multisort($m[1],$m[2]);echo join($m[2]);. Pero tenga en cuenta que se espera que las soluciones manejen la entrada y la salida por sí mismas (a menos que el lenguaje lo haga automáticamente), en lugar de esperar encontrar la entrada en una variable o simplemente dejar el resultado en una variable. Ver meta relacionado .
manatwork
1

Limpio , 277 150 bytes

Yay coincidencia de patrones!

import StdEnv,StdLib
?s=map snd(sort(zip(map(toInt o toString)[takeWhile isDigit h\\['" x="':h]<-tails s],[c\\[c:t]<-tails s|take 7 t==['</text>']])))

Pruébalo en línea!

Define la función ?, tomar [Char]y dar [Char].

Οurous
fuente