Pokonaj SVGCaptcha


79

Natknąłem się na SVGCaptcha i od razu wiedziałem, że to zły pomysł.

Chciałbym, abyś pokazał, jak zły jest to pomysł, poprzez wyodrębnienie kodu weryfikacyjnego z obrazów SVG, które wytwarza kod.


Przykładowy obraz wygląda następująco: Oto źródło przykładowego obrazu:
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>

Dane wejściowe to obraz SVG, który jest formatem tekstowym.

Jedynym prawdziwym ograniczeniem jest to, że kod musi generować wartości we właściwej kolejności .
Elementy wejściowe <text>są w kolejności losowej, więc musisz zwrócić uwagę na xatrybut w <text>znaczniku


Wynik to liczba bajtów w kodzie


Ponieważ kod obecnie wykonuje dwie transformacje, które się wzajemnie znoszą, możesz je zignorować, ale jeśli je weźmiesz pod uwagę, śmiało i weź 30% obniżkę swojego wyniku.


3
Nie określiłeś wprost, jakie są dane wejściowe i wyjściowe: Zakładam, że plik SVG i zawarte w nim litery? I nie jest dla mnie jasne, czy odpowiedzi są wymagane, aby faktycznie zaimplementować specyfikację SVG, czy też mogą założyć, że SVG jest generowany przez bieżącą wersję SVGCaptcha, więc transformacje można zignorować.
Peter Taylor

Sugeruję ograniczenie wyniku do STDOUT lub wartości zwracanej przez funkcję i uczynienie go golfem kodowym
TheDoctor

1
Nie, pytania wymagają obiektywnego, mierzalnego kryterium wygranej, aby były na temat tej witryny.
Alex A.

7
Nie jestem pewien, jak ważne jest tutaj przetwarzanie obrazu .
SuperJedi224,

18
To pytanie jest teraz czwartym wynikiem, gdy googling „svgcaptcha” :)
Blue

Odpowiedzi:


18

Bash , 63 56 39 bajtów

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

Uwaga: wymaga cat, grep , sort, rev, i cut. Pobiera dane wejściowe ze standardowego wejścia. Dane wyjściowe są oddzielone podziałami linii na standardowym wyjściu. Pamiętaj, aby nacisnąć CTRL + D (nie COMMAND + D na Macu) po zakończeniu wprowadzania CAPTCHA. Po wprowadzeniu musi nastąpić nowy wiersz, a następnie „_”.

EDYCJA : Zapisano 13 bajtów.

EDYCJA 2 : Zaoszczędź 20 bajtów dzięki @manatwork !


GNU coreutils sort wspiera pozycję znaku w keydef: cut -c4-|sort -nsort -k1.4n.
manatwork

@manatwork Dzięki, zaktualizowałem odpowiedź.
Coder256

13

CJam, 26 bajtów

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

Wypróbuj online w interpretatorze CJam .

Jak to działa

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 bajtów

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

edycja: -2 bajty zmieniające się documentRootna lastChild; -2 bajty zmieniają się join('')na join``, dzięki Vɪʜᴀɴ

Wpisz kod w konsoli przeglądarki na stronie zawierającej dany plik SVG, zapisuje dane wyjściowe konsoli.


document.rootElementprzestrajanie niezdefiniowane. Wypróbowałem Firefox i Safari
Downgoat

Zostało to przetestowane tylko w Chrome, przyjrzę się temu, co można zmienić.
Nickson

Wygląda na to, że działa w przeglądarce Firefox. Czy SVG jest jedyną zawartością pliku?
Nickson

Okej, wypróbowałem to w Chrome, teraz działa. +1. Możesz także zapisać dwa bajty, zmieniając na ('')dwa backticks: ``
Downgoat

To jest 78: t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))(przyjmuje ciąg xml jako parametr, zwraca tekst captcha)
DankMemes

7

Perl, 40 bajtów

39 bajtów kod + 1 dla -n

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

Przykład:

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

Człowiek, który jest pełen ostrzeżeń, jeśli je włączysz. Doskonałe wykorzystanie domyślnej luźnej natury Perla.
Brad Gilbert b2gills

@ BradGilbertb2gills Tak, staram się nie testować ostrzeżeń, jestem zaskoczony, że jakiś kod do gry w golfa czasami działa!
Dom Hastings,



3

Befunge, 79 bajtów

Wydaje się, że powinno być możliwe zagranie w golfa przynajmniej o jeden bajt, ale pracowałem nad tym już od kilku dni i jest to tak dobre, jak tylko mogłem.

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

Wypróbuj online!

Wyjaśnienie

Kod źródłowy z podświetlonymi ścieżkami wykonania

*Ustaw kierunek wykonywania od prawej do lewej i zawiń, aby rozpocząć główną pętlę.
*Odczytaj char ze standardowego wejścia i sprawdź wartość końca pliku.
*Jeśli nie jest na końcu pliku, sprawdź, czy to >.
*Jeśli nie jest to >, dodaj go do wartości na stosie, która śledzi ostatnie dwa znaki, i sprawdź, czy bieżąca para pasuje x=.
*Jeśli nie, pomnóż przez 126 i mod przez 126 2, aby usunąć najstarszą wartość z pary i zrobić miejsce dla następnej postaci.
*Zawiń się ponownie, aby powtórzyć główną pętlę.
*Gdy x=napotkasz parę, pomiń następny znak (cytat), przeczytaj liczbę całkowitą ( wartość x ) i podziel przez 20. To staje się bieżącym przesunięciem, które jest zapisywane na później.
*Kiedy >napotkasz a, przeczytaj następny znak (zazwyczaj jedną z liter captcha) i zapisz go z bieżącym przesunięciem w „tablicy”. Zresetuj przesunięcie do 9, aby litera captcha nie została nadpisana, gdy >napotkasz późniejsze znaki.
*Wreszcie, gdy osiągnięty zostanie koniec pliku, iteruj 7 wartości zapisanych w tablicy i wysyłaj je jeden po drugim. To powinno dać ci wszystkie litery captcha we właściwej kolejności.

Przeglądam tutaj niektóre szczegóły, ponieważ ścieżki kodu nakładają się na siebie w sposób, który jest nieco trudny do wyjaśnienia, ale powinno dać ogólne wyobrażenie o tym, jak działa algorytm.


2

Python2, 129 bajtów

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

Pobiera źródło HTML na stdin, produkuje kod na stdout.


Jak to sortuje dane wyjściowe? Te <text>elementy są w przypadkowej kolejności, a jedynym wymogiem jest realne, że trzeba umieścić je w odpowiedniej kolejności. Oznacza to, że trzeba używać xz <text>i śledzić transformacji.
Brad Gilbert b2gills

@ BradGilbertb2gills Tęskniłem za pierwszym razem, naprawione teraz.
lub

2

Mathematica, 106 bajtów

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

Uwaga: Dane wejściowe muszą mieć dokładnie format określony w przykładzie.


2

V , 28 26 25 24 bajtów

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

Wypróbuj online!

Wyjaśnienie:

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 bajtów

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

Wypróbuj online!

Znajduje wartości x (cyfry biegną za x=") i „litery” (przypięte przez zamykanie i otwieranie znaczników), a następnie wykonuje następującą APL (gdzie znajduje się lista znalezionych wartości x i liter, w kolejności pojawiania się):

3↓⍵ upuść pierwsze trzy elementy (spacje wokół <rect/rect>i wartość <rect„sx”).

() Zastosuj następującą funkcję ukrytą:

 liczba pozostałych pozycji

.5× połowę tego

2,⍨ dodaj dwa

⊢⍴⍨ zmienić kształt do tego kształtu (tj. macierz n × 2)

 transponuj (do matrycy 2 × n)

⍎¨@1 wykonaj każdy ciąg w pierwszym rzędzie (zamieniając je na liczby)

 podziel macierz na dwa wektory (jeden na wiersz)

x c← przechowuj te dwa odpowiednio w wartości x (wartości x) i c (znaki)

 wybierz pierwszy (x)

 oceniać w górę (indeksy na x, które sortowałyby x)

c[] Użyj tego do indeksowaniac

ε nlist (spłaszczyć), ponieważ każda litera jest ciągiem sama


Równoważne wyrażenie APL całego programu QuadS to:

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

1

Java 8, 197 173 bajtów

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

Wyprowadza a java.util.Collectionznaków.

Wyjaśnienie:

Wypróbuj 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 znaków

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

W Gema nie ma sortowania, ale na szczęście nawet nie jest potrzebne.

Przykładowy przebieg:

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

1

XMLStarlet , 46 znaków

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

Mamy nadzieję, że jest to prawidłowe rozwiązanie, ponieważ XMLStarlet to transpiler, który generuje i wykonuje kod XSLT, który jest kompletnym językiem Turinga.

Przykładowy przebieg:

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

1

PHP, 96 bajtów

Biorąc pod uwagę, że $ijest to ciąg wejściowy

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

1
Zamiast array_combine()+ ksort()można użyć array_multisort()tak: array_multisort($m[1],$m[2]);echo join($m[2]);. Należy jednak pamiętać, że rozwiązania powinny same obsługiwać dane wejściowe i wyjściowe (chyba że język robi to automatycznie), zamiast oczekiwać znalezienia danych wejściowych w zmiennej lub po prostu pozostawienia wyniku w zmiennej. Zobacz powiązane meta .
manatwork

1

Czysty , 277 150 bajtów

Dopasuj wzór!

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

Wypróbuj online!

Definiuje funkcję ?, przyjmowanie [Char]i dawanie [Char].

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.