ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript を使用して検証コードを解読する

JavaScript を使用して検証コードを解読する

高洛峰
高洛峰オリジナル
2016-11-25 09:54:161558ブラウズ

最近、検証コードを解読できる JavaScript スクリプトがインターネット上に登場しました - GreaseMonkey! 「Shaun Friedle」によって開発されたこのスクリプトは、Megaupload サイトの CAPTCHA を簡単に解決できます。信じられない場合は、http://herecomethelizards.co.uk/mu_captcha/ で自分で試してみてください!

さて、Megaupload サイトが提供する CAPTCHA は、正直に言うと、上記のコードには無効です。確認コードはこちら デザインがあまり良くありません。しかし、もっと興味深いのは:

1. HTML 5 の Canvas アプリケーション インターフェイス getImageData を使用して、検証コード画像からピクセル データを取得できます。 Canvas を使用すると、画像を Canvas に埋め込むだけでなく、後でそこから再抽出することもできます。

2. 上記のスクリプトには、完全に JavaScript で実装されたニューラル ネットワークが含まれています。

3. Canvas を使用して画像からピクセル データを抽出した後、それをニューラル ネットワークに送信し、簡単な光学式文字認識技術を使用して検証コードでどの文字が使用されているかを推測します。

ソースコードを読むことで、その動作原理をよりよく理解できるだけでなく、この検証コードがどのように実装されているかも理解できます。前に見たように、ここで使用される CAPTCHA はそれほど複雑ではありません。各 CAPTCHA は 3 つの文字で構成され、各文字は異なる色を使用し、26 文字のアルファベットの文字のみを使用しますが、すべての文字は同じフォントを使用します。

最初のステップの目的は明らかで、検証コードをキャンバスにコピーし、グレースケール画像に変換します。

Function Convert_grey(image_data){
for (var x = 0; 4+y*4*image_data.width; var luma = Math.floor(image_data.data[i] * 299/1000 +
image_data.data[i] +1] * 587/1000 +
image_data.data[i+ 2] * 114/1000);
image_data.data[i+1] = luma; +2] = luma;
image_data.data[i+3 ] = 255;
}
}
}


次に、キャンバスを 1 つの文字を含む 3 つの別々のピクセル行列に分割します。各キャラクターは別々の色を使用するため、色で区別できるため、このステップは非常に簡単に実行できます。

フィルター(画像データ[0], 105);

フィルター(画像データ[2], 135);

関数フィルター(画像データ, 色){
for (var x = 0) ; x image_data.data[i] = 255; 255;

image_data.data[i +2] = 255;
// それ以外は黒にする
} else {
image_data.data[i+1] = 0; data[i+2] = 0 ;
}
}
}
}


最後に、無関係な干渉ピクセルがすべて削除されます。これを行うには、まず前後の黒 (不一致) ピクセルに囲まれた白 (一致) ピクセルを見つけて、一致したピクセルを削除します。

var i = x*4+y*4*image_data.width; 上の var = x*4+(y-1)*4*image_data.width; 下の var = x*4+(y+1) *4 *image_data.width;
if (image_data.data[i] == 255 &&
image_data.data[上] == 0 &&
image_data.data[下] == 0) {
image_data.data[i] = 0 ;
image_data.data[i+1] = 0;
image_data.data[i+2] = 0; これでキャラクターのおおよその形状が得られましたが、ニューラルネットワークに読み込む前つまり、スクリプトは必要なエッジ検出をさらに実行します。スクリプトは、グラフィックの左端、右端、上端、下端のピクセルを検索し、それらを長方形に変換し、その長方形を 20*25 ピクセルのマトリックスに再変換します。

cropped_canvas.getContext("2d").fillRect(0, 0, 20, 25);

varedges = find_edges(image_data[i]);

Cropped_canvas.getContext("2d").drawImage(canvas,edges[ 0]、エッジ[1]、エッジ[2]-エッジ[0]、エッジ[3]-エッジ[1]、0、0、エッジ[2]-エッジ[0]、エッジ[3]-エッジ[1] ]);
Image_data[i] = Cropped_canvas.getContext("2d").getImageData(0, 0,

cropped_canvas.width, Cropped_canvas.height);



上記の処理を行うと、A 20* が得られます。黒と白で塗りつぶされた単一の長方形を含む 25 マトリックス。とても素晴らしいです!

そして、この長方形をさらに単純化していきます。私たちは、ニューラル ネットワークに入力される「光受容体」としてマトリックスからポイントを戦略的に抽出します。たとえば、特定の光受容体は、ピクセルの有無にかかわらず、9*6 に位置するピクセルに対応する場合があります。スクリプトは、そのような一連の状態を抽出し (20x25 の行列計算全体よりもはるかに少なく、64 個の状態のみが抽出されます)、これらの状態をニューラル ネットワークに入力します。

なぜピクセルを直接比較しないのかと疑問に思われるかもしれませんが、ニューラル ネットワークを使用する必要があるのでしょうか? 問題の鍵は、こうした曖昧な状況を取り除く必要があるということです。前のデモを試したことがある場合は、ピクセルを直接比較する方が、それほど多くは発生しないものの、ニューラル ネットワークを介して比較するよりもエラーが発生しやすいことがわかります。しかし、ほとんどのユーザーにとっては、ピクセルを直接比較するだけで十分であることを認めなければなりません。

次のステップは、文字を推測してみることです。 64 個のブール値 (文字画像の 1 つから取得) と、事前に計算された一連のデータがニューラル ネットワークにインポートされます。ニューラル ネットワークの概念の 1 つは、取得したい結果が事前にわかっているため、その結果に基づいてニューラル ネットワークを適切にトレーニングできるというものです。スクリプト作成者はスクリプトを複数回実行し、生成された値から逆算してニューラル ネットワークが答えを推測するのに役立つ一連の最高スコアを収集できますが、これらのスコアには特別な意味はありません。

ニューラル ネットワークが検証コード内の文字に対応する 64 個のブール値を計算し、事前に計算されたアルファベットと比較して、各文字との一致のスコアを与えます。 (最終結果は同様になる可能性があります: 98% が文字 A、36% が文字 B など)

確認コードの 3 つの文字がすべて処理されると、最終結果が表示されます。このスクリプトは 100% 正しいわけではないことに注意してください (最初に文字を長方形に変換しないと採点の精度が向上するのではないかと思います) が、少なくとも現在の目的ではかなり優れています。そう言ってください。そして、すべての操作は標準のクライアント テクノロジに基づいてブラウザ内で完了します!

補足として、このスクリプトは他の単純な検証コードではうまく機能する可能性がありますが、複雑な検証コードではうまく機能します。少し手の届かないところにあります (特にこの種のクライアントベースの分析)。このプロジェクトの可能性は非常に大きいので、より多くの人がこのプロジェクトに触発されて、より素晴らしいものを開発できることを願っています


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。