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 -n→ sort -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.