-5

アルゴリズムを分析する方法を教えてもらえないかと思っていたのですが、先生がいくつかの文字列の検証コードを教えてくれました。そしてアウト プロジェクトは、このバリデーターの keygen を作成する必要があることです。もちろん、検証時に true でなければなりません。私は力ずくで試してきましたが、運がなく、2時間のように機能しています. 今、これを解決する方法に関するヘルプ、アイデア、またはヒントは完璧です。

前もって感謝します。

バリデーターのコードは次のとおりです。

function char2number(chr) {
        var code = chr.charCodeAt(0); 
        if(code<65) code = code-48; 
        else {
             code=code-65+10; 
             if(code>=11) code++;
             if(code>=22) code++; 
             if(code>=33) code++; 
        } 
        return code; 
}

function checkdata(code) { 
        var dig = 0; 
        var test = 1; 
        for(var i=0; i<code.length-1;i++) { 
                dig=dig+(char2number(code.charAt(i))*test);   
                test*=2; 
         } 
        dig = mod(dig,9); 
        if(dig==code.charAt(code.length-1)) return true; 
        else return false; }

 function mod(X,Y) { var t; t = X % Y; return t < 0 ? t + Y : t; }

function valida() {
        var codigo = document.getElementById("code").value;
        // Validate the code
        if( code == "" || code.length < 15 ) {
           alert("Invalid!");
           return false;
        }
        if( ! checkdata(code.toUpperCase()) ) {
           alert("Invalid!");
           return false;
        }

このコードは Javascript で記述されています。これは、ソリューションを Python で詳しく説明し、Python からサービスを呼び出して検証する必要があるためです。コードを作成するのは難しいとは思いませんが、これを解決する方法を考えていて、それを機能させるためのパターンを見つけることができません。

皆さんありがとう!

4

1 に答える 1

2

OK、内部で何が起こっているのcheckdataですか?さて、終了前に何をしていてもdig = mod(dig, 9)、0から8までの数字を取得した後、それを最後の文字(code.charAt(code.length-1)))と比較しています。for上記のループは、i<code.length-1ではなくi<code.length実行するため、最後の文字は計算に含まれないことに注意してください。そして(長さ15+のチェックを除いて)ここでは他に何も起こっていません。

forしたがって、ループ全体が何をしているのかを理解する必要さえありません。14個以上のランダムな文字を生成し、それらに対してまったく同じコードを実行し、結果を最後に追加できる場合は、合格します。

これを行うための迅速で汚い方法の1つは、その最後の直前にalert(または、console.logブラウザーの代わりにノードで使用して実行する…)を追加するcheckdataことdigです。

function checkdata(code) { 
  var dig = 0; 
  var test = 1; 
  for(var i=0; i<code.length-1;i++) { 
    dig=dig+(char2number(code.charAt(i))*test);
    test*=2;
  }
  dig = mod(dig,9);
  alert(dig);
  if(dig==code.charAt(code.length-1)) return true; 
  else return false;}

そこで、「ABC123DEF456GHI789」のように、15文字以上のランダムな文字列を取得します。「2」というアラートがポップアップ表示されますが、2と9が同じではないため、失敗します。したがって、代わりに「ABC123DEF456GHI782」を使用するだけで合格します。

checkdataこれで、その関数をPythonに移植し、に変更alert(dig)return code[:-1] + dig、15文字のランダムな文字列を生成するコードを記述し、もちろんサービスを呼び出すコードを記述するだけです。しかし、それだけです。

ちなみに、Pythonへの移植は、見た目ほど簡単ではありませ。例えば:

  • JS2は、64ビット浮動小数点数です。Python2は無制限のビット整数です。
  • JS文字列はUnicodeです。Python 2.x文字列はそうではありません(しかし3.xはそうです)。
  • 一部のブラウザのJS文字列は、実際にはUnicodeではなくUTF-16です。
  • JS%はサインを保持しています。Python%は常にポジティブです。

幸いなことに、keygenを作成するために、これらの事柄のいずれかが重要な場所の限界を超えないものを生成できますが、そうすることを確認するために物事を熟考する必要があります。

先生は、ループをブラックボックスのように扱うのではなく、ループ内で何が起こっているのかを理解してほしいと思うかもしれないことを付け加えておきます。forまた、実際には、このばかげたアルゴリズムを書いた人は誰でも、あなたがそれをどのように解読したかを理解し、必要なループを少なくとも部分的に理解するような些細な変更を行います(たとえば、に変更した場合<code.length-1<code.length

于 2012-12-28T23:08:40.250 に答える