Đánh bại SVGCaptcha


79

Tôi tình cờ gặp SVGCaptcha , và ngay lập tức biết đó là một ý tưởng tồi.

Tôi muốn bạn chỉ ra ý tưởng này tệ đến mức nào khi trích xuất mã xác nhận từ các hình ảnh SVG mà mã tạo ra.


Một hình ảnh ví dụ trông như thế này: Đây là nguồn của hình ảnh ví dụ:
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>

Đầu vào là hình ảnh SVG, là một định dạng văn bản.

Hạn chế thực sự duy nhất là mã của bạn phải tạo ra các giá trị theo đúng thứ tự .
Các <text>yếu tố đầu vào theo thứ tự ngẫu nhiên, do đó bạn phải chú ý đến xthuộc tính trong <text>thẻ


Điểm là số byte trong mã


Vì mã hiện đang thực hiện hai biến đổi triệt tiêu lẫn nhau, bạn có thể bỏ qua chúng, nhưng nếu bạn cân nhắc chúng, hãy tiếp tục và giảm 30% so với điểm số của bạn.


3
Bạn chưa thực sự tuyên bố rõ ràng đầu vào và đầu ra là gì: Tôi đoán là tệp SVG và các chữ cái có trong đó? Và tôi không rõ liệu câu trả lời có bắt buộc phải thực hiện thông số SVG hay không hoặc liệu họ có thể cho rằng SVG được tạo bởi phiên bản hiện tại của SVGCaptcha hay không và do đó các biến đổi có thể bị bỏ qua.
Peter Taylor

Tôi đề nghị giới hạn đầu ra ở STDOUT hoặc giá trị trả về của hàm và biến nó thành mã golf
TheDoctor

1
Không, câu hỏi cần một tiêu chí chiến thắng khách quan, có thể định lượng để trở thành chủ đề cho trang web này.
Alex A.

7
Tôi không chắc cách xử lý hình ảnh có liên quan ở đây.
SuperJedi224

18
Câu hỏi này bây giờ là kết quả thứ 4 khi googling 'svgcaptcha' :)
Blue

Câu trả lời:


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

Lưu ý: yêu cầu cat, grep , sort, rev, và cut. Lấy đầu vào từ stdin. Đầu ra được phân tách bằng các ngắt dòng trên thiết bị xuất chuẩn. Đảm bảo nhấn CTRL + D (không phải LỆNH + D trên máy Mac) khi nhập xong CAPTCHA. Đầu vào phải được theo sau bởi một dòng mới và sau đó '_'.

EDIT : Đã lưu 13 byte.

EDIT 2 : Đã lưu 20 byte nhờ @manatwork !


GNU coreutils sort hỗ trợ vị trí ký tự trong keydef: cut -c4-|sort -nsort -k1.4n.
thao tác

@manatwork Cảm ơn, tôi đã cập nhật câu trả lời.
Coder256

13

CJam, 26 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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

chỉnh sửa: -2 byte thay đổi documentRootthành lastChild; -2 byte thay đổi join('')thành join``, cảm ơn Vɪʜᴀɴ

Nhập mã trong bảng điều khiển trình duyệt trên một trang có liên quan đến SVG đang được đề cập, ghi vào đầu ra của bàn điều khiển.


document.rootElementđang trả lời không xác định. Tôi đã dùng thử Firefox và Safari
Downgoat

Điều này chỉ được thử nghiệm trong Chrome, tôi sẽ xem xét những gì có thể thay đổi.
Nickson

Nó dường như hoạt động trong Firefox, SVG có phải là nội dung duy nhất của tệp không?
Nickson

Được rồi, đã thử nó trong Chrome, bây giờ nó đã hoạt động. +1. Bạn cũng có thể lưu hai byte bằng cách thay đổi ('')thành hai backticks: ``
Downgoat

Đây là 78: t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))(lấy chuỗi xml làm tham số, trả về văn bản captcha)
DankMeme

7

Perl, 40 byte

Mã 39 byte + 1 cho -n

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

Thí dụ:

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

Người đàn ông chỉ đầy cảnh báo nếu bạn bật chúng lên. Sử dụng tuyệt vời bản chất lỏng lẻo mặc định của Perl.
Brad Gilbert b2gills

@ BradGilbertb2gills Vâng, tôi cố gắng không kiểm tra các cảnh báo, tôi rất ngạc nhiên khi bất kỳ mã golf nào thậm chí đôi khi hoạt động!
Dom Hastings



3

Befunge, 79 byte

Cảm giác như có thể chơi golf ít nhất một byte trong số này, nhưng tôi đã làm việc với nó trong vài ngày nay, và điều này tốt như tôi có thể có được.

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

Hãy thử trực tuyến!

Giải trình

Mã nguồn với các đường dẫn thực thi được tô sáng

*Thực hiện hướng thực hiện từ phải sang trái và quấn quanh để bắt đầu vòng lặp chính.
*Đọc một char từ stdin và kiểm tra giá trị cuối tập tin.
*Nếu nó không phải là cuối tập tin, hãy kiểm tra xem nó có phải là một >.
*Nếu không phải là a >, hãy thêm nó vào giá trị trên ngăn xếp theo dõi hai ký tự cuối cùng và kiểm tra xem cặp hiện tại có khớp không x=.
*Nếu không, nhân với 126 và mod với 126 2 để bỏ giá trị cũ nhất từ ​​cặp và tạo khoảng trống cho ký tự tiếp theo.
*Quấn xung quanh một lần nữa để lặp lại vòng lặp chính.
*Khi gặp một x=cặp, bỏ qua ký tự tiếp theo (trích dẫn), đọc một số nguyên ( giá trị x ) và chia cho 20. Điều này trở thành phần bù hiện tại được lưu lại cho lần sau.
*Khi >gặp a, hãy đọc ký tự tiếp theo (thường là một trong các ký tự captcha) và lưu ký tự đó ở phần bù hiện tại trong một "mảng". Đặt lại phần bù thành 9, vì vậy chữ captcha sẽ không bị ghi đè khi >gặp các ký tự sau này .
*Cuối cùng, khi đạt đến cuối tập tin, lặp lại 7 giá trị được lưu trong mảng và xuất từng cái một. Điều đó sẽ cung cấp cho bạn tất cả các chữ cái captcha theo đúng thứ tự.

Tôi đang xem qua một số chi tiết ở đây, vì các đường dẫn mã chồng chéo lên nhau theo những cách hơi khó giải thích, nhưng nó sẽ cho bạn ý tưởng chung về cách thức hoạt động của thuật toán.


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

Lấy nguồn HTML trên stdin, tạo mã trên thiết bị xuất chuẩn.


Làm thế nào để sắp xếp đầu ra? Các <text>yếu tố theo thứ tự ngẫu nhiên, và yêu cầu thực sự duy nhất là bạn phải đặt chúng theo đúng thứ tự. Điều đó có nghĩa là bạn phải sử dụng xtừ <text>và theo bất kỳ biến đổi nào.
Brad Gilbert b2gills

@ BradGilbertb2gills Tôi đã bỏ lỡ lần đầu tiên, đã sửa bây giờ.
orlp

2

Toán học, 106 byte

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

Lưu ý: Đầu vào cần phải ở chính xác định dạng được chỉ định bởi ví dụ.


2

V , 28 26 25 24 byte

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

Hãy thử trực tuyến!

Giải trình:

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

Hãy thử trực tuyến!

Tìm các giá trị x (chữ số chạy sau x=") và "chữ cái" (được ghim bằng cách đóng và mở thẻ), sau đó thực hiện APL sau (trong đó là danh sách các giá trị x và chữ cái tìm thấy, theo thứ tự xuất hiện):

3↓⍵ thả ba yếu tố đầu tiên (số lượng có khoảng <rect... /rect><rect'giá trị sx).

(... ) áp dụng các chức năng ngầm sau trên rằng:

 số lượng mặt hàng còn lại

.5× giảm một nửa

2,⍨ nối hai

⊢⍴⍨ định hình lại hình dạng đó (tức là ma trận n × 2)

 hoán vị (sang ma trận 2 × n)

⍎¨@1 thực hiện từng chuỗi trong hàng đầu tiên (biến chúng thành số)

 chia ma trận thành hai vectơ (một hàng trên một hàng)

x c← lưu trữ hai giá trị x (x) và c (ký tự) tương ứng

 chọn đầu tiên (x)

 xếp loại (các chỉ số thành x sẽ sắp xếp x)

c[Sọ ] sử dụng nó để lập chỉ mục vàoc

ε nlist (flatten) bởi vì mỗi chữ cái là một chuỗi bằng cách riêng của mình


Biểu thức APL tương đương của toàn bộ chương trình QuadS là:

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

Xuất ra một java.util.Collectionký tự.

Giải trình:

Hãy thử trực tuyến.

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 ký tự

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

Trong Gema không có sự sắp xếp, nhưng may mắn là thậm chí không cần thiết.

Chạy mẫu:

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

1

XMLStarlet , 46 ký tự

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

Hy vọng rằng đây là giải pháp hợp lệ vì XMLStarlet là bộ chuyển mã tạo và thực thi mã XSLT, là ngôn ngữ hoàn chỉnh của Turing.

Chạy mẫu:

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

1

PHP, 96 byte

Cho rằng đó $ilà chuỗi đầu vào

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

1
Thay vì array_combine()+ ksort()bạn có thể sử dụng array_multisort()như thế này : array_multisort($m[1],$m[2]);echo join($m[2]);. Nhưng xin lưu ý rằng các giải pháp được dự kiến ​​sẽ tự xử lý đầu vào và đầu ra (trừ khi ngôn ngữ tự động thực hiện), thay vì mong muốn tìm đầu vào trong một biến hoặc chỉ để lại kết quả trong một biến. Xem meta liên quan .
thao tác

1

Sạch sẽ , 277 150 byte

Phù hợp với mô hình 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>']])))

Hãy thử trực tuyến!

Xác định chức năng ?, lấy [Char]và cho [Char].

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.