-1

Peter Weinberger のハッシュ アルゴリズムを解読することは可能ですか?

独自の Encrypt Decrypt 関数を作成しようとしています。ハッシュ値とは、ハッシュ値を復号化できない、または復号化できないことを意味するという概念を理解していますが、アルゴリズムが比較的単純であるため、この場合、この種のハッシュを復号化できる可能性があると考えています。シンプルなローテーションを使用するシンプルな Encrypt Decrypt を実行しましたが、さらに難しいことを試してみたいと思います。

では、Peter Weinberger のハッシュ アルゴリズムから生成されたハッシュ値を解読することは可能でしょうか?

次の暗号化関数は、Peter Weinberger の正確なハッシュ アルゴリズムです。復号化は、機能していない私自身の試みです。

int encrypt(char *s)
{
    /* Peter Weinberger's */

    char *p;
    unsigned int h, g;
    h = 0;
    for(p=s; *p!='\0'; p++){
        h = (h<<4) + *p; printf("Step : ");
        if (g = h&0xF0000000) {
            h ^= g>>24;
            h ^= g;
        }
    }
    return h % 211;
}

std::string decrypt(int v)
{
    /* Peter Weinberger's */

    unsigned int h, g;
    h = 0;
    v /= 211;
    int s = sqrt(v);

    /* Not sure what to do here
    for(p=s; *p!='\0'; p++){

    }
    */

    return string(h);
}
4

2 に答える 2

3

出力サイズが非常に小さいことを考えると、ブルート フォース攻撃は自明です。

  1. 文字列を生成します (たとえば、ランダムに)
  2. ハッシュする
  3. 既知の値と一致する場合は、最初のプレイメージが見つかりました。そうでない場合は、手順 1 に進みます。

これにより、指定されたハッシュに一致する文字列を取得するために、平均で 211 回の試行が必要になります。おそらく元の文字列ではないでしょうが、ハッシュの損失の多い性質を考えると、それは予想されることです。


2 つの文字入力の場合、このハッシュは(16*s[0]+s[1])%211次のように書き換えることができます。(16*(s[0]-'A')+(s[1]-'A') + 50)%211

あなたが得る文字列を解く:

s[0]=(hash+161)/16+'A';
s[1]=(hash+161)%16+'A';

たとえば、s == "AB"を取得しますhash==51。次に、上記の式を使用して逆にします。

s[0] = 13 +'A' = 'N'
s[1] =  4 +'A' = 'E'

=>s="NE"ハッシュ 51 に一致しますが、元の文字列ではありません。

于 2013-01-12T10:01:04.517 に答える
0

アルゴリズムを正しく理解していれば、文字ごとに次のようになります。

  1. ハッシュを 16 倍します (左に 4 ビット移動します)。
  2. 文字列の文字を追加
  3. 結果が 28 ビットを超える場合は、上位 4 ビットを削除し、ハッシュのどこかで XOR します。

文字列のサイズを 6 (または最初のバイトが 16 未満の場合は 7) に制限することで、ステップ 3 は発生しません。あとは単純なシフトアンド加算だけです。

文字列が 6 文字の場合、最終結果は次の合計になります (h = 文字の上位 4 ビット、l = 下位 4 ビット)。

pos: bits
0: .hl00000
1: ..hl0000
2: ...hl000
3: ....hl00
4: .....hl0
5: ......hl
----------- +
   0*******  Result is 32 bits with upper 4 bits zero

ビット 24 ~ 27 は、位置 0 の文字の上位 4 ビットと、下位ビットの加算による可能な桁上げによって決定されることがわかります。ビット 20 から 23 は、char 0 の下位ビットと char 1 の上位ビットの合計です (プラス可能な桁上げ)。

入力文字が 255 の可能なすべての値 (ゼロを除く) を持つことができる場合、ハッシュを生成する文字列を作成することはそれほど難しくありません。

  1. ハッシュの上位 4 ビットを見てください。これは、位置 0 のキャラクタの高い部分になります。
  2. ハッシュの次の 4 ビットを見てください。これは、char 1 の上位部分と char 0 の下位部分の加算です。
  3. 最も高い部分の値を選択します。たとえば、「最上位は常にゼロ」または「最上位は常に 0100 (大文字)」です。
  4. has のビットが手順 3 で選択した値よりも小さい場合は、前のビットから一部を借ります (これらのビットがゼロの場合は、次のビット グループにリッピングします)。
  5. これで、char 0 の下部と char 1 の上部ができました。
  6. ハッシュの最後に到達するまで、次の 4 ビットについてステップ 2 に戻ります。
  7. 文字列に値が 0 の文字がないことを確認してください。

あらゆる種類のエッジ ケース (ハッシュ 01000000 など) があるため、コードはもう少し複雑になり、読者の演習として残されます ;)。

編集:h % 211操作を完全に逃しました。CodesInChaos が示すように、これによりさらに簡単になります。

于 2013-01-12T10:23:49.917 に答える