2012-01-07 8 views
1

私は以下の関数の逆関数を書こうとしています。別の逆であるJavaScriptで関数を書く

関数fooの出力を取得して、その入力パラメータを生成できるようにします。

可能かどうか完全にはわかりません。

function foo(str){ 
    var hexMap = { 
     "0":0, 
     "1":1, 
     "2":2, 
     "3":3, 
     "4":4, 
     "5":5, 
     "6":6, 
     "7":7, 
     "8":8, 
     "9":9, 
     "A":10, 
     "B":11, 
     "C":12, 
     "D":13, 
     "E":14, 
     "F":15 
    }; 
    var charList = []; 

    str = str.toUpperCase();    


    for (var i = 0; i < str.length; i += 2) { 
     charList.push(hexMap[str.charAt(i)] * 16 + hexMap[str.charAt(i + 1)]); 
    } 

    charList.splice(0, 8); 
    charList.splice(0, 123); 

    var sliceEnd = charList[0] + charList[1] * 256; 
    charList.splice(0, 4); 

    charList = charList.slice(0, sliceEnd); 
    return charList; 
} 
+4

明白な英語で説明してください。私たちにコードダンプを投げずに理解しようとするのではなく、達成しようとしていることは何ですか? –

答えて

3

あなたの関数は、文字として[0-9a-fA-F]のみを使用して16進数の文字列を取ります。次に、2つの16進文字が0から255までの10進整数に変換される配列を作成します。次に、この配列から最初の131個の要素をすぐにスローします。これは、文字列の最初の262文字が関数の出力に影響を与えないことを意味します(最初の262文字は任意の文字です)。

次に、この行がある:

var sliceEnd = charList[0] + charList[1] * 256; 

sliceEndは0と65535の間の数(結果として得られる配列の最大サイズ)となります。入力文字列内のインデックス262〜265の文字に基づく。 (2つの2桁の16進値を2つの整数に変換します.264桁の値に256を掛けて262桁の値に加算します)。

次に、結果の配列には、位置270から270 + sliceEnd * 2までの文字と同じ方法を使用して変換された整数が含まれます。

MSNは、この関数が1対1でないため、数学的に可逆ではないが、0から255までの65536未満の整数の配列を与える関数を書くことができます。その配列を戻す。具体的に次の関数がちょうどそれを行います。

function bar(arr){ 
    var sliceEnd = arr.length; 
    var temp = '00' + (sliceEnd & 255).toString(16); 
    var first = temp.substring(temp.length - 2); 
    temp = '00' + Math.floor(sliceEnd/256).toString(16); 
    var second = temp.substring(temp.length - 2); 
    var str = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + first + second + '0000'; 
    for(var i = 0; i < arr.length; i++){ 
     temp = '00' + arr[i].toString(16); 
     str += temp.substring(temp.length - 2); 
    } 
    return str; 
} 

をこれはあなたの財産を与えることfoo(bar(x)) === x(xは0と255の間に65536の未満の整数の配列である場合には、以前に述べたように)ではなく、財産bar(foo(x)) === xとして理由MSNは、あなたの職務には財産を達成することは不可能だと指摘した。

EG。 (これらの0年代の少なくとも268の値のいずれかの他のことができ[17,125,12,11]が、他の多くの入力があります:あなたはあなたの関数fooへの入力として与える場合は、元の配列を取り戻す

"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000117dcb"bar([17,125,12,11])は、文字列を与えます[0-9a-fA-F]04は04より大きい値をとります。つまり、22^268(255 - 4)の異なる文字列には、小文字か大文字かを考慮に入れるだけで、それ以外には255 - 4^268は、とにかく1つの出力のためのばかげた数の入力です。そして、それらは、上記の文字列で始まり、他の16進文字列を付加した無限の文字列であるという事実を無視しています。 sliceEnd変数が原因です。

+2

+1は実際に右 - 逆を見つけるための努力のために(そしてそれは良い答えです)。 –

3

この関数は1対1の関数ではなく、つまり、多くの入力が同じ出力を生成します。

+0

あなたは 'charList.splice'を呼び出して入力文字列の一部を捨ててしまいます。 –

+0

彼は文字列の一部を捨てることができますが、その部分を取り除くためのパターンがある場合に限り、元に戻すことができます。 – marcio

関連する問題