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>タグ内の属性に注意する必要があります


スコアはコードのバイト数です


現在、コードは相互にキャンセルする2つの変換を行うため、無視できますが、それらを考慮する場合は、スコアを30%引き下げてください。


3
あなたは実際に入力と出力が何であるかを明確に述べていません:私はSVGファイルとそこに含まれる文字を推測していますか?そして、SVG仕様を実際に実装するために回答が必要かどうか、またはSVGがSVGCaptchaの現在のバージョンによって生成されると想定できるので、変換を無視できるかどうかは明確ではありません。
ピーターテイラー

出力をSTDOUTまたは関数の戻り値に制限し、コードゴルフに
TheDoctor

1
いいえ、質問には、このサイトのトピックであるための客観的で定量化可能な勝利基準が必要です。
アレックスA.

7
ここで画像処理がどの程度関連しているかはわかりません。
SuperJedi224

18
この質問は、「svgcaptcha」をグーグルで検索したときの4番目の結果になりました:)
ブルー

回答:


18

Bash63 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 grepsortrev、とcut。stdinから入力を受け取ります。出力は、stdoutの改行で区切られます。CAPTCHAの入力が終了したら、Ctrl + Dキー(MacではCommand + Dキーではない)を押してください。入力の後に改行が続き、その後に「_」が必要です。

編集:13バイトを保存しました。

編集2@manatworkのおかげで20バイトを節約しました


GNU coreutils sortは、keydefの文字位置をサポートします:cut -c4-|sort -nsort -k1.4n
マナトワーク

@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バイトdocumentRootlastChild;に変更 変化-2バイトjoin('')join``、おかげVɪʜᴀɴ

問題のSVGを含むページのブラウザコンソールにコードを入力し、コンソール出力に書き込みます。


document.rootElement未定義に戻しています。FirefoxとSafariを試しました
-Downgoat

これはChromeでのみテストされたもので、何が変更される可能性があるかを調べます。
ニックソン

Firefoxで動作するようですが、ファイルのコンテンツはSVGのみですか?
ニックソン

さて、Chromeで試してみましたが、今はうまくいきました。+1。また、2 ('')つのバック
ティックに

これは78です:(t=>(l=[],r=/x="(\d*).*?>(.)/g,eval("while(e=r.exec(t))l[e[1]]=e[2];l.join``"))パラメーターとしてxml文字列を受け取り、
キャプチャ

7

Perl、40バイト

-nの場合は39バイトのコード+ 1

$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バイト

これで少なくとももう1バイトはゴルフができるように思えますが、私はここ数日作業を続けてきました。

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

オンラインでお試しください!

説明

実行パスが強調表示されたソースコード

*実行方向を右から左にし、ラップしてメインループを開始します。
*stdinからcharを読み取り、ファイルの終わりの値をテストします。
*ファイルの終わりではない場合は、かどうかを確認します>
*aでない場合>、最後の2文字を追跡するスタックの値に追加し、現在のペアが一致するかどうかを確認しx=ます。
*そうでない場合は、126で乗算し、126 2で modしてペアから最も古い値を削除し、次の文字用のスペースを作ります。
*メインループを繰り返すには、もう一度ラップアラウンドします。ペアが検出され
*たら、x=次の文字(引用符)をスキップし、整数(x値)を読み取り、20で除算します。これが現在のオフセットになり、後で保存されます。
*が検出されたら、>次の文字(通常はキャプチャ文字の1つ)を読み取り、それを「配列」の現在のオフセットに保存します。オフセットを9にリセットすると、後の>文字が検出されたときにキャプチャ文字が上書きされなくなります。
*最後に、ファイルの終わりに達すると、配列に保存されている7つの値を反復処理し、それらを1つずつ出力します。これにより、すべてのキャプチャ文字が正しい順序で表示されます。

コードパスは互いに説明するのが少し難しい方法で重なり合っているため、ここで詳細の一部を説明しますが、アルゴリズムの仕組みの一般的なアイデアを提供するはずです。


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

stdinでHTMLソースを取得し、stdoutでコードを生成します。


これはどのように出力をソートしますか?<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

V28 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の値(数字の後に続く数字x=")と「文字」(閉じタグと開始タグで固定)を検索し、次のAPLを実行します(検出されたxの値と文字のリスト、出現順)。

3↓⍵ 最初の3つの要素(<rect…の前後のスペース/rect><rect'sx値)をドロップします。

() 次の暗黙関数を適用します:

 残りのアイテムの数

.5× それを半分に

2,⍨ 2つ追加する

⊢⍴⍨ その形状に再形成する(すなわち、n×2行列)

 転置(2×n行列に)

⍎¨@1 最初の行の各文字列を実行します(数字に変換します)

 行列を2つのベクトル(行ごとに1つ)に分割します

x c← これら2つをそれぞれx(x値)およびc(文字)に保存します

 最初の(x)を選ぶ

 グレードアップ(xをソートするxへのインデックス)

c[…を] 使用してインデックスを作成するc

εの各文字が文字列はそれ自体であるためNLIST(平坦化)


QuadSプログラム全体の同等のAPL式は次のとおりです。

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

1

Java 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

Gema、65文字

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

Gemaには並べ替えはありませんが、幸いなことに並べ替えは必要ありません。

サンプル実行:

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]);。ただし、ソリューションは入力および出力自体を処理することが期待されていることに注意してください(言語が自動的に処理しない限り)。関連するメタを参照してください
マナトワーク

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.