Поражение SVGCaptcha


79

Я наткнулся на SVGCaptcha и сразу понял, что это плохая идея.

Я хотел бы, чтобы вы продемонстрировали, насколько это плохая идея, извлекая проверочный код из изображений SVG, создаваемых этим кодом.


Пример изображения выглядит следующим образом: Вот источник изображения примера:
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>

Входные данные - изображение SVG, которое является текстовым форматом.

Единственное реальное ограничение - ваш код должен выдавать значения в правильном порядке . Элементы
ввода <text>расположены в случайном порядке, поэтому вы должны обратить внимание на xатрибут в <text>теге


Оценка - это количество байтов в коде.


Поскольку код в настоящее время выполняет два преобразования, которые взаимно компенсируют друг друга, вы можете их игнорировать, но если вы все-таки учтете их, продолжайте и получите 30% -ное снижение от вашей оценки.


3
Вы на самом деле не указали явно, что такое ввод и вывод: я предполагаю SVG-файл и содержащиеся в нем буквы? И мне не ясно, требуются ли ответы для фактической реализации спецификации SVG или они могут предположить, что SVG генерируется текущей версией SVGCaptcha, и поэтому преобразования можно игнорировать.
Питер Тейлор

Я предлагаю ограничить вывод значением STDOUT или возвращаемым значением функции и сделать его code-golf
TheDoctor

1
Нет, вопросы должны быть объективными, измеримыми критериями выигрыша, чтобы быть в теме для этого сайта.
Алекс А.

7
Я не уверен, насколько важна обработка изображений здесь.
SuperJedi224

18
Этот вопрос стал четвертым результатом поиска в Google 'svgcaptcha' :)
Blue

Ответы:


18

Баш , 63 56 39 байт

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

Примечание: требуется cat, grep , sort, rev, и cut. Принимает ввод от стандартного ввода. Вывод разделен переносами строк в stdout. Убедитесь, что вы нажали CTRL + D (не COMMAND + D на Mac), когда закончили ввод капчи. За вводом должен следовать символ новой строки, а затем «_».

РЕДАКТИРОВАТЬ : Сохранено 13 байтов.

РЕДАКТИРОВАТЬ 2 : Экономия 20 байтов благодаря @manatwork !


GNU coreutils sort поддерживает положение символов в keydef: cut -c4-|sort -nsort -k1.4n.
manatwork

@manatwork Спасибо, я обновил ответ.
Coder256

13

CJam, 26 байтов

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

Попробуйте онлайн в интерпретаторе CJam .

Как это устроено

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 байт

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

редактировать: -2 байта меняется documentRootна lastChild; -2 байта меняется join('')на join``, спасибо Vɪʜᴀɴ

Введите код в консоли браузера на странице, связывающей SVG, о которой идет речь, пишет в вывод консоли.


document.rootElementперенастраивается не определено. Я пробовал Firefox и Safari
Downgoat

Это было проверено только в Chrome, я посмотрю, что можно изменить.
Никсон

Похоже, что работает в Firefox, SVG является единственным содержимым файла?
Никсон

Ладно, попробовал в Chrome, теперь все заработало. +1. Вы также можете сохранить два байта, изменив ('')две метки: ``
Downgoat

Это 78: t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))(принимает строку XML в качестве параметра, возвращает текст с
картинки

7

Perl, 40 байт

39-байтовый код + 1 для -n

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

Пример:

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

Человек, который просто полон предупреждений, если вы их включите. Превосходное использование слабой природы Perl по умолчанию.
Брэд Гилберт b2gills

@ BradGilbertb2gills Да, я стараюсь не проверять предупреждения, я так удивлен, что любой гольф-код даже иногда работает!
Дом Гастингс



3

Befunge, 79 байт

Такое ощущение, что можно было бы сыграть в гольф хотя бы еще один байт из этого, но я работаю над этим уже пару дней, и это настолько хорошо, насколько я смог получить.

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

Попробуйте онлайн!

объяснение

Исходный код с выделенными путями выполнения

*Сделайте направление выполнения справа налево и оберните вокруг, чтобы начать основной цикл.
*Прочитайте символ из стандартного ввода и проверьте значение конца файла.
*Если это не конец файла, проверьте, если это >.
*Если это не a >, добавьте его к значению в стеке, которое отслеживает последние два символа, и проверьте, совпадает ли текущая пара x=.
*Если нет, умножьте на 126 и модифицируйте с 126 2, чтобы отбросить самое старое значение из пары и освободить место для следующего символа.
*Оберните снова, чтобы повторить основной цикл.
*При обнаружении x=пары пропустите следующий символ (кавычку), прочитайте целое число ( значение x ) и разделите на 20. Это становится текущим смещением, которое сохраняется для последующего использования.
*Когда >встречается a , прочитайте следующий символ (обычно одну из букв капчи) и сохраните его с текущим смещением в «массиве». Сбросьте смещение на 9, чтобы буква капчи не была перезаписана при >обнаружении более поздних символов.
*Наконец, когда достигается конец файла, переберите 7 значений, сохраненных в массиве, и выведите их одно за другим. Это должно дать вам все заглавные буквы в правильном порядке.

Я здесь приукрашиваю некоторые детали, поскольку пути кода перекрывают друг друга способами, которые немного сложно объяснить, но это должно дать вам общее представление о том, как работает алгоритм.


2

Python2, 129 байт

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

Принимает исходный код HTML на стандартный ввод, производит код на стандартный вывод.


Как это сортирует вывод? Эти <text>элементы находятся в случайном порядке, и единственное реальное требование заключается в том , что вы должны поместить их в правильном порядке. Это означает, что вы должны использовать xfrom <text>и следовать любым преобразованиям.
Брэд Гилберт b2gills

@ BradGilbertb2gills Я пропустил это в первый раз, исправил сейчас.
orlp

2

Mathematica, 106 байт

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

Примечание. Входные данные должны быть точно в формате, указанном в примере.


2

V , 28 26 25 24 байта

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

Попробуйте онлайн!

Объяснение:

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 байтов

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

Попробуйте онлайн!

Находит значения х (цифры идут после x=") и «буквы» (закреплены закрывающими и открывающими тегами), а затем выполняет следующую APL (где находится список найденных значений х и букв в порядке появления):

3↓⍵ отбросьте первые три элемента (пробелы вокруг <rect... /rect>и значение <rect'sx).

() Примените к этому следующую молчаливую функцию:

 количество оставшихся предметов

.5× вдвое

2,⍨ добавить два

⊢⍴⍨ изменить эту форму (то есть матрица n × 2)

 транспонировать (в матрицу 2 × n)

⍎¨@1 выполнить каждую строку в первом ряду (превратив их в числа)

 разбить матрицу на два вектора (по одному на строку)

x c← сохранить эти два в x (значения x) и c (символы) соответственно

 выбрать первый (х)

 оценка (индексы в х, которые будут сортировать х)

c[... ] использовать это для индексации вc

ε NLIST (сплющить) , потому что каждая буква является строкой самого по себе


Эквивалентное выражение APL всей программы QuadS:

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

1

Ява 8, 197 173 байта

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

Вывод java.util.Collectionсимволов.

Объяснение:

Попробуйте онлайн.

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

Гема , 65 знаков

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

В гема нет сортировки, но, к счастью, даже не нужна.

Образец прогона:

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

1

XMLStarlet , 46 символов

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

Надеемся, что это правильное решение, так как XMLStarlet является транспортером, который генерирует и выполняет код XSLT, который является полным языком Тьюринга.

Образец прогона:

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

1

PHP, 96 байт

Учитывая, что $iэто входная строка

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

1
Вместо array_combine()+ ksort()можно использовать array_multisort()следующим образом: array_multisort($m[1],$m[2]);echo join($m[2]);. Но учтите, что решения должны обрабатывать ввод и вывод самостоятельно (если язык не делает это автоматически), вместо того, чтобы ожидать, что вы найдете вход в переменной или просто оставите результат в переменной. Смотрите связанные мета .
Манатворк

1

Чисто , 277 150 байт

Yay образец соответствия!

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

Попробуйте онлайн!

Определяет функцию ?, принимая [Char]и давать [Char].

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.