0

このアルゴリズムを元に戻すのに苦労しています:

decrypt_algorithm = function (text) {
  var parser = new TextParser(text);
  var decrypt_key = [16, 19, 17, 7, 20, 23, 13, 1, 24, 15, 6, 12, 0, 18, 21, 2, 9, 14, 3, 10, 5, 25, 8, 4, 22, 11];
  var text_size = parser.getSize();
  var text_size_without_last_part = text_size - 26;
  var output = [];
  if (text_size_without_last_part > 0) {
      for (var m = 0; m < text_size_without_last_part; m += 26) {
          var word_to_decrypt = [];
          for (var k = 0; k < 26; k++) {
              word_to_decrypt[k] = parser.readNextChar()
          }
          for (var k = 0; k < 26; k++) {
              output[m + k] = word_to_decrypt[decrypt_key[k]]
          }
      }
      var parser_position = parser.getPosition();
      var last_part_size = text_size - text_size_without_last_part - 1;
      if (last_part_text > 0) {
          for (var k = 0; k < last_part_size; k++) {
              output[text_size_without_last_part + k] = parser.readNextChar()
          }
      }
  }
  return output;
};

私はリバース エンジニアリングの知識がないので、関数を「リバース」する方法を説明しているリソースを教えていただければ、非常に役に立ちます。

答えとして正確なコードは必要ありませんが、自分でリバースエンジニアリングする方法に関するいくつかのガイドは本当にありがたいです.

編集1:

一時停止してアルゴリズムについて少し考えた後、私は問題を理解し、思ったより簡単でした。

output[decrypt_key[k]] = word_to_decrypt[m + k]

これを変更するとアルゴリズムが元に戻り、問題が解決します。

4

2 に答える 2

4

単純な順列暗号です。基本的にdecrypt_key、出力を再配置するために使用されます

output[m + k] = word_to_decrypt[decrypt_key[k]]


decrypt_key = [16, 19, 17, 7, 20, 23, 13, 1, 24, 15, 6, 12, 0, 18, 21, 2, 9, 14, 3, 10, 5, 25, 8, 4, 22, 11];

または、次のように並べ替えます。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 16 17 18 19 20 21 22 23 24 25

コード

word_to_decrypt[decrypt_key[k]]

基本的に、「暗号化」されているコードにインデックスを取り込み、その単語を 26 個のチャンクに並べ替えます。

どのようにスクランブルされているかを示す「キー」に基づいて単語をスクランブルしているだけと考えることができます。

例えば、

decrypt_key[0] -> 16
decrypt_key[16] -> 9

これは、最初の単語 (位置 0) が位置 16 に配置され、位置 16 の単語が位置 9 に配置されることを意味します。

別の用語は、それをシャッフル暗号と呼ぶことです。すべての単語をシャッフルしますが、非常に予測可能な方法です。

暗号の種類と種類を知っている限りdecypher_key、カードがどのようにシャッフルされたかを正確に知っていれば、カードのデッキでできるのと同じように、データを非常に簡単に復元できます (真にランダムではないため)。

逆暗号を作成するには、反対の鍵を作成する必要があります。位置 0 が 16 になった場合、それは位置 16 が 0 に移動する必要があることを意味します。配列内の各数値に対してこれを行い、「encrypt_key」と呼ばれる新しい配列を形成すると、適切に復号化できる単語を暗号化する方法が得られますあなたが与えたコード。


ルアコード:

function printarray(arr) local s = '[' for k,v in pairs(arr) do s = s..tostring(v)..', '  end s = s:sub(1,-3)..']' return s end
function permute(arr, key) local newarr = {}; for i = 1, #key do newarr[i] = arr[key[i]] end return newarr end

letters = {'a','b','c','d','e'};
key = {5, 1, 3, 4, 2};
invkey = {}
newletters = permute(letters, key)
print('input:  '..printarray(letters))
print('key:    '..printarray(key))
print('output: '..printarray(newletters))


for i = 1, #key do
    for j = 1, #key do
        if i == key[j] then
            invkey[i] = j;
            break;
        end
    end
end;

newletters2 = permute(newletters, invkey)
print('\nInverse Permutation')
print('input:  '..printarray(newletters))
print('key:    '..printarray(invkey))
print('output: '..printarray(newletters2))

出力:

input:  [a, b, c, d, e]
key:    [5, 1, 3, 4, 2]
output: [e, a, c, d, b]

Inverse Permutation
input:  [e, a, c, d, b]
key:    [2, 5, 3, 4, 1]
output: [a, b, c, d, e]
于 2012-11-14T01:48:15.130 に答える
2

リバース エンジニアリングを行う必要はありません。JavaScript のソース コードは既にあります。アルゴリズムは単純に見えます (ネストされた 2 つのループのみ)。デバッガーでステップ実行するだけで、「キー」が特定の入力にどのように関連しているかが明らかになります。

アルゴリズムは対称に見えるので、キーが何をするかを理解したら (キーに従って文字列内の文字をシャッフルするだけのように見えます)、暗号化関数を導き出すことができます。

于 2012-11-14T01:37:13.657 に答える