Sconfiggi SVGCaptcha


79

Mi sono imbattuto in SVGCaptcha e ho subito capito che era una cattiva idea.

Vorrei che mostrassi quanto sia cattiva questa idea estraendo il codice di convalida dalle immagini SVG prodotte dal codice.


Un'immagine di esempio è simile alla seguente: Ecco la fonte dell'immagine di esempio:
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>

L'input è l'immagine SVG, che è un formato testuale.

L'unica vera limitazione è che il codice deve produrre i valori nell'ordine corretto .
Gli <text>elementi di input sono in ordine casuale, quindi devi prestare attenzione xall'attributo nel <text>tag


Il punteggio è il numero di byte nel codice


Poiché al momento il codice esegue due trasformazioni che si annullano a vicenda, puoi ignorarle, ma se le prendi in considerazione, vai avanti e prendi una riduzione del 30% dal tuo punteggio.


3
In realtà non hai dichiarato esplicitamente quali sono l'input e l'output: presumo il file SVG e le lettere in esso contenute? E non mi è chiaro se sono necessarie risposte per implementare effettivamente le specifiche SVG o se possono supporre che SVG sia generato dalla versione corrente di SVGCaptcha e quindi le trasformazioni possano essere ignorate.
Peter Taylor,

Suggerisco di limitare l'uscita a STDOUT o il valore di ritorno della funzione e di renderlo code-golf
TheDoctor

1
No, le domande necessitano di un criterio vincente oggettivo e quantificabile per essere in tema per questo sito.
Alex A.

7
Non sono sicuro di quanto sia rilevante l' elaborazione delle immagini qui.
SuperJedi224,

18
Questa domanda è ora il 4 ° risultato quando si cerca su Google "svgcaptcha" :)
Blu,

Risposte:


18

Bash , 63 56 39 byte

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: richiede cat, grep , sort, rev, e cut. Riceve input dallo stdin. L'output è separato da interruzioni di riga su stdout. Assicurati di premere CTRL + D (non COMANDO + D su Mac) al termine dell'inserimento di CAPTCHA. L'input deve essere seguito da una nuova riga e quindi da '_'.

EDIT : salvato 13 byte.

EDIT 2 : salvato 20 byte grazie a @manatwork !


Coreutils GNU sortsupporta la posizione dei caratteri nel keydef: cut -c4-|sort -nsort -k1.4n.
arte

@manatwork Grazie, ho aggiornato la risposta.
Coder256,

13

CJam, 26 byte

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

Provalo online nell'interprete CJam .

Come funziona

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#

8

JavaScript, 95 93 91 byte

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

modifica: -2 byte cambiando documentRootin lastChild; -2 byte cambiando join('')in join``, grazie Vɪʜᴀɴ

Immettere il codice nella console del browser in una pagina contenente l'SVG in questione, scrive nell'output della console.


document.rootElementsta risintonizzando indefinito. Ho provato Firefox e Safari
Downgoat il

Questo è stato testato solo in Chrome, esaminerò cosa potrebbe essere cambiato.
Nickson,

Sembra funzionare in Firefox, SVG è l'unico contenuto del file?
Nickson,

Ok, l'ho provato su Chrome, ora ha funzionato. +1. Puoi anche salvare due byte modificando i ('')due backtick: ``
Downgoat

Questo è 78: t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))(accetta la stringa xml come parametro, restituisce il testo captcha)
DankMemes

7

Perl, 40 byte

39 byte codice + 1 per -n

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

Esempio:

perl -ne '$a[$1]=$2 for/x="(.+)".+(.)</g}{print@a' <<< '<example from above>'
8u4x81f

L'uomo che è solo pieno di avvertimenti se li accendi. Ottimo uso della natura rilassata di default di Perl.
Brad Gilbert b2gills

@ BradGilbertb2gills Sì, provo a non testare gli avvisi, sono così sorpreso che qualsiasi codice golfizzato funzioni anche a volte!
Dom Hastings,



3

Befunge, 79 byte

Sembra che dovrebbe essere possibile giocare a golf con almeno un byte in più, ma ci sto lavorando da un paio di giorni, e questo è il massimo che ho potuto ottenere.

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

Provalo online!

Spiegazione

Codice sorgente con percorsi di esecuzione evidenziati

*Crea la direzione di esecuzione da destra a sinistra e avvolgi per avviare il loop principale.
*Leggi un carattere da stdin e verifica il valore di fine file.
*Se non è la fine del file, controlla se è un >.
*Se non è un >, aggiungilo al valore nello stack che tiene traccia degli ultimi due caratteri e controlla se la coppia corrente corrisponde x=.
*In caso contrario, moltiplicare per 126 e mod con 126 2 per eliminare il valore più vecchio dalla coppia e creare spazio per il carattere successivo.
*Avvolgere di nuovo per ripetere il ciclo principale.
*Quando x=viene rilevata una coppia, salta il carattere successivo (la citazione), leggi un numero intero (il valore x ) e dividi per 20. Questo diventa l'offset corrente che viene salvato per dopo.
*Quando >viene rilevato un, leggi il carattere successivo (in genere una delle lettere captcha) e salvalo nell'offset corrente in un "array". Reimpostare l'offset su 9, in modo che la lettera captcha non venga sovrascritta quando >vengono rilevati caratteri successivi .
*Infine, quando viene raggiunta la fine del file, scorrere i 7 valori salvati nell'array e inviarli uno alla volta. Questo dovrebbe darti tutte le lettere captcha nell'ordine corretto.

Sto analizzando alcuni dei dettagli qui, poiché i percorsi del codice si sovrappongono in modi che sono un po 'difficili da spiegare, ma dovrebbe darti un'idea generale di come funziona l'algoritmo.


2

Python2, 129 byte

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])))

Porta il sorgente HTML su stdin, produce codice su stdout.


In che modo questo ordina l'output? Gli <text>elementi sono in un ordine casuale e l'unico vero requisito è che devi metterli nell'ordine corretto. Ciò significa che devi usare il xda <text>e seguire le trasformazioni.
Brad Gilbert b2gills

@ BradGilbertb2gills L'ho perso la prima volta, risolto ora.
orlp,

2

Mathematica, 106 byte

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

Nota: l'input deve essere esattamente nel formato specificato nell'esempio.


2

V , 28 26 25 24 byte

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

Provalo online!

Spiegazione:

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..

2

QuadS , 49 byte

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

Provalo online!

Trova i valori x (digit-run after x=") e "lettere" (appuntati chiudendo e aprendo i tag), quindi esegue il seguente APL (dove si trova l'elenco dei valori x trovati e delle lettere, in ordine di apparizione):

3↓⍵ rilascia i primi tre elementi (spazi attorno a <rect... /rect>e il <rectvalore 'sx).

(... ) applica la seguente funzione tacita su quella:

 il numero di elementi rimanenti

.5× dimezzalo

2,⍨ aggiungere un due

⊢⍴⍨ rimodellare a quella forma (cioè una matrice n × 2)

 trasporre (su una matrice 2 × n)

⍎¨@1 esegue ogni stringa nella prima riga (trasformandola in numeri)

 dividere la matrice in due vettori (uno per riga)

x c← memorizzare quei due rispettivamente in x (valori x) e c (caratteri)

 scegli il primo (x)

 grado (gli indici in x che ordinerebbe x)

c[... ] usalo per indicizzarec

ε nlist (appiattire) perché ogni lettera è una stringa di per sé


L'espressione APL equivalente dell'intero programma QuadS è:

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

1

Java 8, 197 173 byte

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();}

Emette a java.util.Collectiondi caratteri.

Spiegazione:

Provalo online.

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

1

Gema , 65 caratteri

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

A Gema non c'è ordinamento, ma per fortuna non è nemmeno necessario.

Esecuzione di esempio:

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

1

XMLStarlet , 46 caratteri

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

Speriamo che questa sia una soluzione valida poiché XMLStarlet è un transpiler che genera ed esegue il codice XSLT, che è un linguaggio completo di Turing.

Esecuzione di esempio:

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

1

PHP, 96 byte

Dato che $iè la stringa di input

preg_match_all('|x="(\d+).*(.)\<|',$i,$m);$a=array_combine($m[1],$m[2]);ksort($a);echo join($a);

1
Invece di array_combine()+ ksort()è possibile utilizzare array_multisort()in questo modo: array_multisort($m[1],$m[2]);echo join($m[2]);. Ma tieni presente che le soluzioni dovrebbero gestire l'input e l'output stessi (a meno che la lingua non lo faccia automaticamente), invece di aspettarsi di trovare l'input in una variabile o lasciare semplicemente il risultato in una variabile. Vedi meta correlata .
arte

1

Pulito , 277 150 byte

Yay pattern matching!

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>']])))

Provalo online!

Definisce la funzione ?, prendendo [Char]e dando [Char].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.