暗号ハッシュゴルフ(強盗)


12

このコンテストは終了しました。

警官のチャレンジには、クラック可能な答えは残っていません。

暗号ハッシュゴルフのコンパニオンスレッド

念のため、主な課題からの強盗のルールを以下に示します。

仕事

スレッドの強盗に次のように掲載することにより提出警官のいずれかをクラック:二つのメッセージMNIように H(M)= H(N)およびM≠N

得点

各警官の提出物をクラックすると、1ポイントが得られます。最も多くのポイントを持つ強盗が勝ちます。

同点の場合、最長の提出をクラックした縛られた強盗が勝ちます。

追加のルール

  • すべての警官の提出は、一度しかクラックできません。

  • 警官の提出が実装定義または未定義の動作に依存している場合、マシン上で(検証可能に)動作するクラックを見つけるだけで済みます。

  • 各クラックは、強盗のスレッドの個別の回答に属します。

  • 無効なクラッキングの試みを投稿すると、その特定のサブミッションを30分間クラッキングできなくなります。

  • あなた自身の提出物をクラックすることはできません。

Python 2.7、user8675309による22バイト

1

そして

18

リーダーボード

  1. eビジネス:クラック3回、393バイト
  2. MartinBüttner:クラック3回、299バイト
  3. jimmy23013:3つのクラック、161バイト
  4. Sp3000:3つのクラック、44バイト
  5. tucuxi:2つのクラック、239バイト
  6. Vi .:クラック2回、87バイト
  7. feersum:1クラック、216バイト
  8. mathmandan:1クラック、139バイト
  9. squeamish ossifrage:クラック1、134バイト

回答:


5

C、122バイト-by:Mr. Llama

bmaj8PCosFLAJjeHaevvvchnJedmg2iujpePOPivI2x2asw0yKa2eA15xvFJMFe82RGIcdlvxyaAPRuDuJhFjbh78BFsnCufJkarwEyKa0azHxccw5qegpcP9yaO0FKoohanxgiAfK1Lqwba51bKtjacbvdjMmcBkiv8kd62sBd98c4twa98sgj3iPh7nkP4
rlaejTPrua1DhBdg0jrIoDBi8fc1GIJAigivIGaxs1OmfPcctNadK3HErvzPLCeDPD8fkMNPCBcIwuoGfEHegOfk9k9pwktslqaBenaati1uNthMiyk9ndpy7gdIz88iot6A09cbNeIMheyjBvbeegL7aGp7mCb91hCxnvgV5abfImrPfLbrbraAsN6loJgh

両方の文字列がハッシュします bb66000000000000d698000000000000

「C、128バイト-by:squeamish ossifrage」と同様に、上位ビットが下位ビットに影響を与えることはありません。これは悪用される可能性があります。

コード

Visual C ++、「安全でない」文字列操作を使用

#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>

long long x, y;

//Original hash function (not used for cracking).
void h(char inp[]){
    long long c;
    int index = 0;
    int len = strlen(inp);
    x = 0;
    y = 0;
    long long p = 0;
    for (c = 9; c ; c = (index<len?inp[index++]:-1) + 1) {
        for (++p; c--;) {
            x = x*'[3QQ' + p;
            y ^= c*x;
            y ^= x ^= y;
        }
    }
    printf("%016llx%016llx\n", x, y);
}

//Partial hash, takes a string and a starting point in the stream.
//The byte 0x08 must be prepended to a string in order to produce a full legal hash.
void hp(char inp[],long long p){
    long long c;
    int index = 0;
    int len = strlen(inp);
    x = 0;
    y = 0;
    for (index = 0; index<len; index++) {
        c = inp[index] + 1;
        for (++p; c--;) {
            x = x*'[3QQ' + p;
            y ^= c*x;
            y ^= x ^= y;
        }
    }
}

//Reverse partial hash, backtracks the inner state.
void hprev(char inp[], long long p){
    long long c;
    long long clim;
    int index = 0;
    int len = strlen(inp);
    p += len + 1;
    x = 0;
    y = 0;
    for (index = len-1; index>=0; index--) {
        clim = inp[index] + 1;
        c = 0;
        for (--p; c<clim;c++) {
            y ^= x;
            x ^= y;
            y ^= c*x;
            x -= p;
            x = x * 17372755581419296689;
            //The multiplicative inverse of 1530089809 mod 2^64.
        }
    }
}
const int rows = 163840;
const int maprows = 524288;

//Store for intermediate input strings, row 0 contains 64 columns with 3-char strings,
//row 1 contain 32 columns with 6-char strings and so forth, the final strings will
//contain one string from each column, in order.
char store[7][rows][512];

//Storage for a hashmap, used for matching n strings with n string in O(n) time.
char map[maprows][512];

int _tmain(int argc, _TCHAR* argv[])
{
    char alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int row;
    int col;
    int layer;
    int a=0, b=0, c=0;
    int colzero;
    //Produce some starting strings.
    for (row = 0; row < rows; row++){
        //All column 0 strings begin with 0x08 in order to imitate the hash.
        store[0][row][0] = 8;
        colzero = 1;
        for (col = 0; col < 64; col++){
            store[0][row][col * 8 + colzero] = alpha[a];
            store[0][row][col * 8 + colzero + 1] = alpha[b];
            store[0][row][col * 8 + colzero + 2] = alpha[c];
            store[0][row][col * 8 + colzero + 3] = 0;
            colzero = 0;
        }
        a++;
        if (a >= 52){
            b++;
            a = 0;
            if (b >= 52){
                c++;
                b = 0;
            }
        }
    }
    //Layer for layer, column for column, build strings that preserve successively
    //more zero bits. Forward calculated partial hashes are matched with backwards
    //calculated partial hashes.
    for (layer = 1; layer < 7; layer++){
        int slayer = layer - 1;
        int swidth = 1 << (slayer + 3);
        int width = 1 << (layer + 3);
        int slen = 3 << slayer;
        int len = 3 << layer;
        int colnum;
        int layershift=slayer*8;
        for (col = 0,colnum=0; col < 512; col+=width,colnum++){
            printf("Layer: %i, column: %i\n",layer,colnum);
            memset(map, 0, sizeof map);
            int col2 = col + swidth;
            for (row = 0; row < rows; row++){
                hprev(store[slayer][row] + col2, 1 + slen*(1 + colnum * 2));
                x = (x >> layershift) & 255;
                y = (y >> layershift) & 255;
                int index = (x << 3) | (y << 11);
                for (a = 0; a < 8; a++){
                    if (map[index + a][0] == 0){
                        strcpy_s(map[index + a], store[slayer][row] + col2);
                        break;
                    }
                }
            }
            int destrow = 0;
            for (row = 0; row < rows && destrow < rows; row++){
                hp(store[slayer][row] + col, !!colnum + slen*(colnum * 2));
                x = (x >> layershift) & 255;
                y = (y >> layershift) & 255;
                int index = (x << 3) | (y << 11);
                for (a = 0; a < 8 && destrow < rows; a++){
                    if (map[index + a][0]){
                        strcpy(store[layer][destrow] + col, store[slayer][row] + col);
                        strcat(store[layer][destrow] + col, map[index + a]);
                        destrow++;
                    }
                }
            }
        }
    }
    memset(map, 0, sizeof map);
    char temp[1000];
    std::ofstream myfile;
    myfile.open("hashout.txt");
    for (row = 0; row < rows; row++){
        hp(store[6][row], 0);
        sprintf(temp, "%016llx%016llx", x, y);
        myfile << store[6][row] <<" " << temp << "\n";
    }
    myfile << "\n";
    //The final hash set has 96 of 128 output bits set to 0, I could have gone all
    //the way, but this is enough to find a collision via the birthday paradox.
    for (row = 0; row < rows; row++){
        hp(store[6][row], 0);
        long long xc = x;
        long long yc = y;
        int pos = (xc >> 45 | ((yc >> 48) & 7)) & (maprows-1);
        while (map[pos][0]!=0){
            hp(map[pos], 0);
            if (x == xc && y == yc){
                myfile << store[6][row] << "\n" << map[pos] << "\n";
                sprintf(temp,"%016llx%016llx", x, y);
                myfile << temp << "\n\n";
            }
            pos = (pos + 1) % maprows;
        }
        strcpy_s(map[pos], store[6][row]);
    }
    myfile.close();
    printf("done");
    getchar();
    return 0;
}

驚くばかり!私は実際に奇妙な方法で光栄に思っています!:D
ミスターラマ

また、私自身の個人的な教育では、高位のビットが低位のビットに影響を与えないと言うとき、どういう意味ですか?入力文字列の上位ビット、またはハッシュ状態の上位ビット?
ラマ氏

@ Mr.Llamaハッシュ状態では、xとyの上位ビットが下位ビットに影響を与えることはありません。たとえば、計算中に中間ビットをオンにすると、ハッシュの下位部分は依然として正しく出力されます。これにより、ハッシュ状態の最下位ビット以外をすべて無視し始め、それらを完全に制御できるようになったら、次のビット層に進みます。
aaaaaaaaaaaa

涼しい!説明してくれてありがとう!
ラマ氏

強盗チャレンジに勝ちました。おめでとうございます!
デニス

12

Python、Sp3000で109バイト

Martinが最初にクラックしたことに注意してください。したがって、これがポイントに値するかどうかはわかりません。一方、単純な衝突ではなく、プリイメージ攻撃を行いました-より強力な結果です。これは、任意のハッシュ値を指定できることを意味し、そのハッシュ値を生成する入力を作成します。

M = 2**128

# The hash to crack.
def jenkins(n):
    h = 42
    while n:
        h += n & (M - 1)
        n >>= 128
        h *= 1025
        h ^= h >> 6
        h %= M

    h *= 9
    h ^= h >> 11
    h *= 32769

    return h % M

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def invxorshift(h, s):
    r = h >> s
    while r:
        h ^= r
        r >>= s
    return h

def moddiv(a, b):
    return (a * modinv(b, M)) % M

def jenkins_crack(h):
    h = moddiv(h, 32769)
    h = invxorshift(h, 11)
    h = moddiv(h, 9)
    h = invxorshift(h, 6)
    h = moddiv(h, 1025)
    h -= 42
    return h

そして、それが機能することを示すために:

>>> from crack import *
>>> n = 2**128 + 1337
>>> h = jenkins(n)
>>> n2 = jenkins_crack(h)
>>> h2 = jenkins(n2)
>>> n != n2
True
>>> h == h2
True

そして、衝突する特定の数値セットを与えるには:

N: 2**128
M: 43617

3
サンドボックスでの私の最初の提案は、衝突、プレイメージ、および(わずかに単純化しすぎた)長さ延長攻撃に対してポイントを与えましたが、スコアリングを単純にすることにしました。これらのパーツを編集すると、すべての提出が1度しかクラックできないという事実(これが警官と強盗の通常の動作です)が何らかの形で失われました。あなたの答えを見ると、プリイメージ攻撃を続けていたらいいのに…
デニス

9

Python、Sp3000で109バイト

340282366920938463463374607431768211414

そして

113982837842983129870077688367927159293402923522160868689804433865221255200726

両方の収量

132946164914354994014709093261515948032

アルゴリズムは、入力を128ビットのチャンクに分割42し、最後に追加のハッシュを行う前に、各チャンクでハッシュ(シード)を繰り返し変更します。衝突を見つけるための目標は、各チャンクで次の擬似コードを実行した後、同じ結果が得られる2つの数値を見つけることです。

hash += chunk
hash += (hash << 10)
hash ^= (hash >> 6)
hash %= 2**128

ハッシュはmod 2 128で取得されるため、このビット範囲外のすべての興味深いものをシフトする数値を探したいと思います。ただし、ハッシュにはシードが42設定されているため、最初からそれほど重要ではないビットが設定されています。

000000000000000000000000 ... 000000000000000000101010

私のアイデアは、最初のチャンクを追加するときにこれらのビットを取り除くことでした。2 128 -42を試してみましょう。

           000000000000000000000000 ... 000000000000000000101010     hash = 42
           111111111111111111111111 ... 111111111111111111010110     chunk = 2**128 - 42
          1000000000000000000000000 ... 000000000000000000000000     hash += chunk
10000000001000000000000000000000000 ... 000000000000000000000000     hash += hash << 10
10000010001000001000000000000000000 ... 000000000000000000000000     hash ^= hash >> 6
           000001000000000000000000 ... 000000000000000000000000     hash %= 2**128

これは非常に簡単なので、2つの数値の1つとして使用してみましょう。(実際、私が使用した衝突の最初の数は2 128 -42です。

では、どのようにして同じ結果の別の数値を見つけるのでしょうか?1回の反復の後、ハッシュは42もうありませんが、2**122先ほど示したとおりです。ここで、入力番号に2番目のチャンクを追加することにより、別の反復を実行できます。この引数と同じ引数で2番目のチャンクを選択できます。つまり、2 128 -2が必要です。 122が必要です。その後の中間結果hash += chunkは同じになり、最後に同じ結果になります。

したがって、衝突の2つの数値を計算できます。

>>> 2**128-42
340282366920938463463374607431768211414L
>>> 2**128-42 + ((2**128-2**122)<<128)
113982837842983129870077688367927159293402923522160868689804433865221255200726L

このように、さらに多くの衝突を簡単に生成できます。


私もこれをクラックしていました-ほとんど完了しました。これは西のコンテストで最速の銃ですか、それとも投稿するためのポイントを得ることができますか?
orlp

@orlp通常、最初の強盗のみがポイントを獲得します。そうでなければ、最初のクラックが投稿されると、人々は数百万の追加のクラックを生成することができます。
マーティンエンダー

1
ラメ= /この挑戦をやめると思います。私は他人とのレースを楽しんでいません-私はただパズルをしたいです。1人あたり1つだけのクラックで、最初のクラックの後、クラックの時間枠はありませんか?
orlp

@orlpサンドボックスの元のバージョンには、警官をクラッキングする3つの異なる方法があり、3つすべてを個別に投稿できました。これはある時点で調査する興味深いモデルだと思います。ただし、これまでのCnRでは、複数のクラックを許可することで、改善するよりも常に課題を克服できていました。
マーティンエンダー

1
衝突ではなく、プリイメージ攻撃に対する私の答えを参照してください:)
orlp

8

Mathematica、LegionMammal978による89バイト

0

そして

16

両方とも収穫し0ます。

この警官の原理は、「ランダムな」ステップ数の「ランダムな」初期条件から「ランダムな」バイナリ1次元セルオートマトンを進化させ、結果の最初の128セルを整数として解釈することです。

問題はMod[#^2,256]、16の倍数がruleを与えるように、ルールが単にによって決定されることです0。これは、すべてのセルが常にゼロである単純なルールです。入力が99で割り切れない場合、少なくとも1ステップ進化するため、出力は常にゼロになります。したがって、99の倍数ではない2つの倍数は必ず衝突します。ただし、初期条件は入力のバイナリ表現であるため(この場合はすべてゼロ)、入力0 0になります(ルールを使用しないにもかかわらず)。

余談ですが、ルールから完全に独立した他の衝突を見つけることができます。上記のように、99の倍数はセルラーオートマトンがまったく進化しないことを意味するため、結果は単純に初期条件の最初の(最上位)128ビットであり、それ自体が単なる入力番号です。したがって、最初の128ビット(右側にゼロが埋め込まれている)が変わらない2つの倍数を取ると、衝突も発生します。これの最も簡単な例はM = 99N = 99*2 = 198です。


8

J、39バイト

最初の番号は次のとおりです。

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000

つまり、1000000064回繰り返されます。2番目の数字は1を足したものです。つまり、

10000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000010000001

両方の収量

322124197561777885386414076216564234267

説明

のは、始めましょうx := H 10000000 = 146018215378200688979555343618839610915、とy := 2^128。むしろ見つけるよりa, bなるようa == b mod y私たちが見てみましょう、a, bということなx^a == x^b mod y、アルゴリズムでパワータワーを利用し、ます。

しかし、いくつかがなければならないkことなどx^k == 1 mod yから、x, y互いに素であり、そのためにk我々が持っている必要がありますa == b mod k。したがって、1 modの離散対数を見つけることができy、最初のステップでは

x ^ (k = 85070591730234615865843651857942052864) == 1 mod 2^128

だから今、私たちはそのa, bような2つの数字を見つけたいですa == b mod k。これを行うには、あるように設定yし、そのようなものをもう一度k探します。同じロジックを使用して、離散対数を再度取得し、取得しますa, bx^a == x^b mod y

x ^ (k = 21267647932558653966460912964485513216) == 1 mod 85070591730234615865843651857942052864

小さい値yに到達するまでこれを繰り返します。その時点で、同じものを法としてハッシュする2つの数値を見つけるのは簡単yです。63回の反復後y = 4、その時点で基本的に任意の2つの数値が機能します。

離散ログチェーンを生成するMathematicaコードは次のとおりです。

k = 0; x = 146018215378200688979555343618839610915; y = 2^128; While[y > 10, y = MultiplicativeOrder[x, y]; k++; Print[k, " ", y]];

これにより、次の出力が得られます


わずかに短いバージョンでは、最初の数百桁が同じ場合、入力の残りの部分が何らかの方法で問題になる可能性はほとんどありません。実際にこれを破るために数学を行うことはやり過ぎです。
aaaaaaaaaaaa

@eBusinessそれは本当です。ここではそれほど重要ではないことが判明しましたが、最初は2^(2^30)制限を超えてしまうことが心配だったため、チェックしました。
Sp3000

実際、512桁目以降が重要な文字列を作成することは不可能であると思われます。最悪のシナリオを作成することができました。最も簡単なクラックは、内部の先行ゼロ「100000001」「1000000001」を利用することです。
aaaaaaaaaaaa

7

Pyth、FryAmTheEggmanによる8バイト

99999999999999999999999999

そして

99999999999999999999999998

浮動小数点の精度は、これには十分ではありません。


私は実際にこれに対して異なる結果を得ていますが、この戦略はとにかくうまくいくと信じているので、クラックされたものとしてマークします。速い仕事:P
FryAmTheEggman

うーん、変だ。私437409784163148は両方を得る。なぜ違いがあるのか​​しら
...-Sp3000

あなたはおそらくPython 3.5を使用していますか?私はまだアップデートしていませんが、まだ3.4ではそれでいいのでしょうか?
FryAmTheEggman

@FryAmTheEggman実際にオンラインインタープリターを使用しています
...-Sp3000

実はええ私が取得437409784163148し、37409784163148私はそれはいくつかの理由で最後の数字を失ったと思いますので、しかし、99 ... 997 999 ... 98と同じ答えを与えます。
FryAmTheEggman

6

CJam、44バイト、 ユーザー jimmy23013

数字は大きすぎて投稿できないため、ここではPastebinにあります:num 1num 2

最初の数字は 600^2 = 360000 1です。2番目の番号は、次の変更を除いて同じです。

Positions to change to "2": 605, 1811, 3001, 6603
Positions to change to "4": 1805, 3003, 57348, 208895
Positions to change to "5": 602, 1201, 2405, 3004
Positions to change to "6": 1203, 1802
Positions to change to "7": 12, 609, 5401, 7200
Positions to change to "8": 1, 2, 4, 6, 600, 1200, 1808, 2400, 3600, 4803

両方ともハッシュし271088937720654725553339294593617693056ます。

説明

コードの前半を見てみましょう。

lW%                e#  Read input number as string, and reverse
600/               e#  Split every 600 digits, forming a 2D array
_z                 e#  Duplicate and zip, swapping rows and columns
{           }%     e#  For both arrays...
 JfbDb             e#  Find sum of S[i][j]*13^i*19^j, where S are the character values
                   e#  and the indices are from right to left, starting at 0.
      GK#          e#  Take modulo 16^20

         ...  ...  e#  (Rest of code irrelevant)

したがって、合計S[i][j]*13^i*19^jが同じモジュロになるように2つの入力数を見つけることができる場合16^20、最初の600ワイド配列とzip配列の両方に完了です。

物事をもう少し簡単にする600^2 = 360000ために、600桁の配列がちょうど600 x 600の数字になるように、1 桁の入力番号のみを考慮します。これにより、物事を視覚化するのが簡単になります10^360000 ~ 2^(2^20.19) < 2^(2^30)。さらに簡素化するために、元の配列と圧縮された配列が同じになるように、数字の正方形が主対角線に沿って対称であるような入力文字列のみを考慮します。これにより、最初の文字列の反転と、互いに相殺される右から左へのインデックス番号付けを無視することもできます。

まず、最初の数字を1にすることができ360000ます。2番目の数字を取得するには、数字の一部を変更して、合計がmodulo 16^20になるように変更し、数字の正方形の対称性を維持します。トリプルのリストを見つけることでこれを達成します(i, j, k)ので、

sum of k*(13^i 19^j + 19^i 13^j) == 0 mod 16^20

ここで1 <= k <= 8、桁1を増やす量(つまり、桁を2から9に変更する-0を含めることはできましたが、必要ありませんでした)0 <= i < j < 600はインデックスペアです。

私たちが持っていたら(i, j, k)トリプレットを、我々はで数字を変更(i, j)して(j, i)1+k秒数を取得します。トリプレットは、貪欲なバックトラッキングアルゴリズムを使用して検出され、数字の上の2番目の数字は次のようになります。

188181811111711 ...
815112111711111 ...
851611111111111 ...
116114118112111 ...
811115111111111 ...
121451111111111 ...
811111111111111 ...
111111111111111 ...
111811111111111 ...
171111111111111 ...
111111111111111 ...
111211111111111 ...
711111111111111 ...
111111111111111 ...
111111111111111 ...

............... .
...............  .
...............   .

たとえば(i, j, k) = (0, 1, 7)、数字(0, 1)(位置600*0 + 1 = 1)および(1, 0)(位置600*1 + 0 = 600)をに変更することに対応し1 + 7 = 8ます。


Python 3のバックトラッカーは次のとおりです。ただし、実際にバックトラッキングが行われなかったため、詳細な調査により幸運だったことがわかりました。

n = 16**20
L = [(k *(pow(13,i,n)*pow(19,j,n) + pow(19,i,n)*pow(13,j,n)) % n, i, j, k)
     for i in range(600) for j in range(600) for k in range(1, 9) if i < j]

L.sort(reverse=True)
stack = [(n, 0, [])]

while stack:
    k, index, result = stack.pop()

    if k == 0:
        print(result)
        break

    if index == len(L):
        continue

    stack.append((k, index+1, result)) # Don't include triplet

    if L[index][0] <= k:
        stack.append((k - L[index][0], index+1, result + [L[index][1:]])) # Include

ボーナスのために、ここにあるハッシュのそれほど効率的でないポートは、それが役に立たなかった3 Pythonで。


5

PHP 4.1、Ismael Miguelによる66バイト

$ A=0111129112911291111111111111111111111111 php hash.php 2> /dev/null ; echo
0100038003800381129111111111111111111111
$ A=0111129112911291129111111111111111111111 php hash.php 2> /dev/null ; echo
0100038003800381129111111111111111111111
$ cat hash.php 
<? $a = getenv("A"); for($l=strlen($b.=$a*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

1から始まる単純な反復ハッシュを使用して見つかりました。

$ i=1; while true; do i=$(A=$i php hash.php  2> /dev/null); echo $i; done | head -n 10
0111111111111111111111111111111111111111
0100000000000001129111111111111111111111
0111129111111111111111111111111111111111
0100038000000001129111111111111111111111
0111129112911111111111111111111111111111
0100038003800001129111111111111111111111
0111129112911291111111111111111111111111
0100038003800381129111111111111111111111
0111129112911291129111111111111111111111
0100038003800381129111111111111111111111

うん、それは割れている。そこに到達するのにどれくらい時間がかかりましたか?
イスマエルミゲル

2回目。最初の試行は最初の100個のハッシュの値を調べることであり、2番目の試行はハッシュチェーンの作成(つまりhash(hash(hash(...(hash(1)...))))でした。最初のチェーンは、ほぼ瞬時にループに収束しました。マルチスレッドハッシュクラッカーを起動する必要さえありませんでした。
Vi。

翻訳:かなり弱いハッシュ?
イスマエルミゲル

Yes.󠀠󠀠󠀠󠀠󠀠󠀠
Viに。

5

Python 3(216)by Sp3000

私のメッセージは

5012053369354645637214643587103597313576086380250249302980438772005248488380915054746146050001036696049972235875591571028140916001206596142280971107479334216535925703480968283657357930602076844092875640359192729378384507238123245417656548512647301639542279794868512420586823155070914644206130805893968511673770843170450832829657206145931885656157628306896903719624729809643572222159364893644113710867223921580178741177106141068298067479650611992859787419779579962211254029169589775046869542029842374359998053713002047081002506346875804341770199884355810931652447801492691887376948615365487982834690942054717077615539311699691010938426302886867891090301248321702485904291177813145565144089044261424329155436660979948932491709511914065619715728353376578192548334780893602675684085757434059540582004872746967999949306946618036846307799677491651967418565531672392468089533111553281620101129322575737949904022139471688252420467041529301533363008476437812216585923822571793353317799365005036029476865
5012053369354645637214643587103103086948976188724715498910865650846170784131001427390927276355140411160919276493388206817700368694224128444524223814513348177926532982330730066315320819293979046126543806115318009892783577432467861426768883700930779409885418980853424256180864755881414774514084197887594253752179391098292488771920695965135791582218083012144604515253506370334133858904659263953147111654656123599460222236152128559750436960308887683690915261431659087040402402092795259541564130228515353133867041828417398395559815392177084002004583988047406317670433664624642858480970640416500369367395538257341309676777745698712896295462462064271676447460293684100001583256400774270688958051470568447233589146620275159126426142305307007744396679875427883384557759778766330566230012377845843842097372663092379922300568052486301863154557664156185573021849420011058607321977550938866119133331529852821217331665195832442542012455132139770813510559894254061471149750738447764616026512400623344132554752

これらを生成するために、このPython 2コードを使用しました。

a,b = 14460445391122031029,16815296360833931837 #http://www.numberempire.com/numberfactorizer.php
pr = ~-a * ~-b

m0 = reduce(long.__or__, [long(b) << 26*i for i,b in enumerate(bin(pr)[2:])])
m1 = 1 << 26*i-1
m0 |= m1

#print m0, m1
print f(m0), f(m1)

大きなモジュラスは2つの素数aとの積でしたb。セミプライムを因数分解することはNP不可能であることを望んでいたと思いますが、128ビットはWebページがすぐに答えてくれるので小さすぎると思います。

モジュロ乗法群abには順序があります(a-1)(b-1)になります。つまり、任意の数をそのべき乗する場合、0または(通常)1になります。 2 (a-1)(b-1)はハッシュに乗算されます。次に、他のメッセージは基本的に0ですが、長さを同じにするために各番号に1ビットを設定します。

すべての素数を使用した後だけではなく、ハッシュがすべてのビットで2乗されていれば、もっと面倒だったと思います。そうすれば、それらの任意の指数を作成することはそれほど簡単ではなかったでしょう。


良い仕事:)ええ、私が念頭に置いていた脆弱性は、基本的にコード内にセミプライムが見えるということでした。
Sp3000

+1あなたのコードは読みにくいですが、それ以外の場合はすてきで有益なクラックです。
aaaaaaaaaaaa

5

C、128バイト-by:squeamish ossifrage

次の2つの文字列は両方ともすべてゼロにハッシュされます。

dddl|lddH4|@dhxdxXdh0TXPdhhdx(dTxtlpdd@4Lhd|hdDpdhDdXLdXP4(PdddL|ldXdD(lddX4|0hddp4|ddP4Lxdp0dP@dhpTxPdhXdXxdhHDxHdllLttdhPT8pd(pT8Pdd0TL8dlLLTtddPtl8dP@DPPdhhDxhd804(pdh0Txpd@DDpLdhL4xtdXXdHXdd04lXht40dlddh4|@ddPTLXdhhDXHhtPH40dh0t8pd(pt80dhPtX0dhLtXtdhLT8thlLplTdhpt80dh0txpdhHDX(hdX8txdhhdxHdp|d@tdhlTx4dlptdxdh0T8PdT@t|Hdd@tL(ht(8DhdhHD8(hpHHP8dhLtXtdX8dhxdhpt8Pd@(D@Hdd@tLhdtxTLPdd0tlxhhL8X|dd8t|0dT04|Xddxt|phxxxhhdhpt8PhhxX8hdhlTX4dd4l||dd@TLHdXlTHtdhHd8hdX0THPdh(D8(d8xdh8dhp4xPd0HDp(dhl4xTdxlthtdhlTx4d8lT(TdhhdXHdphdP(dhp4x0d0Xd0XddTl||d88DH8dhhdxhdx|tHDdhLT8Thll0lTddPTlXdxXd(xdd0Tlxdhp480dhp4x0dd|LltdhPt80dtll|dddPTlXdxXd(xdd0Tlxdhp480dhp4x0dd|LltdhPt80dtll|dddP4Lxd|ptT8dhddxldH|4xDdhp4x0dDdl|LdhtD8|hhHx88ddpTL8hhphx@dhtd8|dphDP(dh0tx0hhDHx4dhpt8Pd@(D@HddLLLDhh|xxldhl4xTdhL4x4dhPt8Pd(HDx(dh(D8Hd4PT|8ddH4|@hh4H8ddhxd8XdDP4lxdhHd8hdl04d8ddXT|phdh8Thdd@TlHdhXdxxdllL44dD@4lHdhxdxXhd8XtxddLlLddT@T|(dhxdXXd|P44Xdhpt8pdlHDT0dhL4Xtd@ldpDdddl|LdXP4h0dhltXtdX8d(Xdh|tXdhhLXX|dhxd8XdP@D0PdhXDxXhtpHtPdd84|pddtl||dh(dx(d88Dh8ddx4|PhtT0DLdd@tL(hdX8Txdhp480d08d08dlll44d4dLLldhTdX|hh8Xxhdh048pd08d08ddPtL8d4H4l@dhhdxHd|pt4Xddp4lXhp(hPxdh|48DdxhDh(ddLlldd8XdH8dddl|LdLHDT0dhpt8pdlHDT0dh(d8hdTHtl@ddptl8dt84LPdh8dxxdlptD8dd04lxhhH8XxddDl|ldP|D@4ddTl||d|ptT8dh(dXhhd8X48dhPtXpd(8DxXdh@TX@dDP4L8dhpTX0d4@4|hdhHdxHdX8DHxdhPT8PhllplTdh0TXPhlXHLXddp4lXhtHXD(dhP4X0htH8dhdhLTx4hpxHPHdhhd8(dX8DHxdhpt80hhdHxTdlll44d@Hd@(dhhDxhdh0t8Pddh4|@ddh4|@dhptx0dpPD0@ddPtlxdhPT8pdhhdX(htTpDLdd@4L(dLHDtpdhxd8xdt84lPdlpTdxdDPTLXddLLLDdxlThtdlhd4PdXLTh4ddptLxd|@44(dhhd8HdtDLLlddxt|pd|hDd0ddPtLXhl@H|pdhDD8ld8dDhLdhXDXxdDxT|PdhHD8hdp8dpxdhp480d@XD@xddpTLXdHhD8(ddllLDdD|LL4dhpt80d@LdPDdh|4xDdP8dpXddLllddl8d4@dhptXpdd(4|@dhltx4d0Dd@LdhptxphdPHdpdhl4xTdxlthtdhHD8HdTdllldhLtX4dXP4(PdhLTxTd4X4LpddlllDdlpTD8dllltTdL(dtPdhDDxLdhLTx4dhptx0d|0T4Xdhl4xTdHL4XtdhpTXpdLp4dxddHt|@dHL484dhHDXHdHLtxtdhDdXldxL4H4dh|TxDhh8xX(dhLt8td8Lt(TdhHDx(d4DlLlddXT|PdHHD8(dlll44dlP4dxdd@tL(dL@4dhdd0tLxd4X4l0dhhdxhdDlLldddLLlddD04l8ddPtlxd(hd8hdd(T|@hdDp4|ddP4Lxdp0dP@dhptXpd(p4X0dhhd8(d8pT(0dh8d8Xhd(XT(dhddxLd@XD@8dd@tlhd@ld0ddhTD8|hhPH8@ddtl||dH0Tx0ddLlLddhp480dhHdxhd4lL|DdhXD8xdhhDX(dh048pd4Ll|ddddl|LdXP4h0dlll4thhdhxtddP4LXdhXdxXdhpTX0hdXXtxddlLLddx0Th0ddTl||hlhhlHdd|Ll4dHDdXldhhDX(hpxh0HdhDDXLdXDDhLdlhDTpht8Xdxdhpt8phhHXX8dd(t|@dHl4xtddp4LXhxhXH8dhDDxldDXt|PdhTDX|d|0ttxdhdDXLdDLLLddd84|PdT84LpdlhDTphl8hlxdhXD8xdHpt8Pdlhd40ddHT|@dhxdX8dhlT84dh|T8dhlXHLxdhxDxXdT4lL|dlllttd@xd@xdhhDXHhtXXD8dh(d8(d4p4|8dd04lxdxPThpdhHD8Hhdhx4hdhl4xthl|pLDdhltX4dhP4XPdd0Tlxdl@tDhddP4lXd0xD0xdhHD8Hd@8D@xdh0T8Pd0XDpxddPtl8dP@DPPdhhDxhd804(pdd04L8hpxHphdhDdxLdppD0@dd@tl(d88dHXdh0txpdXhDhHdd@Tlhdx8DHXdh0tXPdxxdH8dhPT8Pd484LPdlhD4pdxxdHxdd|Lltdhptx0dhlTx4hp8HPhdhPt8pdt4lL|ddtl||dH0Tx0dhxd8xhl@H|pddLllDhldP||dhdD8ldXLTHTdlhDTpddllLddd04lxhhH8Xxdh|48DdP8d0XddLLldd|@44hdhhd8hd4x4L0dhltXthh4H8Ddh4DX|dD@Tlhdh0tXpd8|T(ddhtDX|dlhdTPdd@tLhdThTl@dh8D8xdT(TL@dd@Tl(d8Hd(hdhXdxxhtHXdhdd0tl8d|HDDPdd8T|PdH04xPdd@Tl(d|@4t(dd(4|@dHp4xpdhpt80dh0txpdhp48phdXxTxdhhDXHhtPH40dh0t8pd(pt80dd8T|pdlxdt@dhp48PdD0TLXdh0t8Pd|lldTdh|t8DhphHp8

ddTl||d4|L|4dhptX0d4dllLddxT|pdxXdH8dlhDtPhlpH|@dd|Lltdhptx0dhlTx4hp8HPhdhPt8pdt4lL|ddtl||dH0Tx0ddLLLDd8tdH|dhDD8LdtxtLpdhxD8Xhd8xtxdhPt8Pd(8DX8dhddxLd0xd08dd0Tlxdxdd(Lddh4|@dXpt(Pdh048pd0xd0xdhhDX(d8p4Hpdh0480d(8DX8dhL4x4d4PT|XddPTLXdPDd@Ldddl|ld(P4X0ddDL|lht88DXdhPtxpd((Dx(dh0tx0dxXd(8dhpT8Pd0xD0XdlhD4pdT0T|8dh04XPht0H40dlhDtpdpHDP(dhlTXtdPHdpHdhXDxXhpPH0pddDl|lhltp|Ldh04x0dtXTL0ddLLLDdLhdtpdhL4xtdHDdXLddxt|0d4X4l0dh(Dxhdx04h0ddllLDd0PD0@dhXDxxhdx848dhDDxldpXDpXdhPt8pdhltxTdd04lxhhH8Xxdh|48DdP8d0XddLLldd|@44hdhhd8hd4x4L0dhltXthh4H8Ddh4DX|dD@Tlhdh0tXpd8|T(ddhtDX|dlhdTPdhlTXtdTX4L0dd@Tlhhh8xXHdhPt80d|XdD@dhp4xphd4Ptldd|LL4dL|ltDdhPTx0d80T(pdhpt8pd|pTtXdhpTX0hhth8Ddhxd8xdphdP(dh8D88dp(DPhdhHD8(htxXdXdh8dXXdXpTH0ddx4|PdpXDPxdhXDXXdxxdhXdhlt8Td@xD@8dhP4XPdhltX4dd@tlHdhXDxxdhPtXPd(8Dxxdh0t8PhdpHd0dh(D8HdX(D(Hdd@tLhht|@4Tdd@4lHdttll|dd0tlXhh|xxldd@TLHdlHdTPdd|LL4dt@T|hddx4|PdlHdtPddTl||d88DH8dlhdTpd40t|xddht|@dpPDP@dhHDxHhxthHDdhddxldxtDH|dhltx4d8Dd(ldd|LLthp0H0Pdhl4x4d|0T4Xdd|ll4dt8tLPdd@4lhd|0TTXddPtLXd(8d8xdhPTxPdHxd8xdhHDX(ddLllddhp48Pd0@d0PdhptxpdX(DhHdd0TlXhtPHTPddh4|@dTDlLldhDDxLhp(hPxdhdD8ldXLTHTddPtLXdTh4L@dhLtxTdlpTd8dhPtXpdhLtX4ddPTlXdxxdhXdhhd8(d404|8dhTd8|dhL4Xtddp4l8d4X4LpdhL4Xtd@ldpDdddl|LdXP4h0dhpTX0htXxDxdhpt8pddLlLddhp4XPhp0H00dh4Dx|dlp4D8dhPtxpd((Dx(dh0tx0dxXd(8dhDDxlhlL0ltdhhDxHd@|d0TdhHdxhdL0tD8dhhD8hhl|pLdddxt|pd|hDd0ddPtLXhl@H|pdhxDXxd8DdhldlhdtphpphppdhpT8PdH8dxXdlhd40dtXtlPdhTd8|dXlthtdhTDX|dx|4HDddxT|pdHDd8ldhL4X4dhP4XpdhtDx|ddXt|Pdh|T8DdHhdxhddLLLDhlxHl8dh0tXPd|(ddPddDL|LdHhdxhdhp4x0dl8dT@ddXT|phdh8Thdh(DXhd0HDP(dddl|lhd(xT(dhXdXxdTxtl0dd|lLtd8|4hddd4l||dXLTh4dd04lxdP8DP8ddxT|0dXXdh8ddP4lxd0@DpPdh8dXxddp4lxdhLt8tdHTdx|dh4Dx|dxLTHtdhhd8hd@DDpldd04LXdXlT(tdhXdXxdhPT8pdh(DXHdP@dp0ddP4LXdXpThPdllL4td((D8(dh0tXpd|(ddpdh(DxhhdL@DDdhHDx(dxL4(tdhLtXtdl@4dHdhxd8xdTh4L@dhXDXXhhdH8Tdd8T|PdH04xPdlllT4hllpLtdhhDXHhxxXhhdhXDxXdPDd@Ldd0TlXdHLtX4ddDL|ldXLT(4dhPtXPdXXd(8dhpt8phdH8thddxT|pd(ptXpddP4LxdLXDT@dhpT80dLptDxddxt|pdP@Dp0dhptx0d|0T4XdlpTdxdxpt(PdhHD8(d4TlL|dhHDx(d@hD@(dd@tl(d88dHXdh(Dx(d4pT|xddPtl8dP@DPPdhhDxhd804(pdhHD8Hhdhx4hddP4lxhdhXt(dhxdX8dp@DppdlllT4dP0dp@dddl|ldH8DXXdllLT4dPXdp8dd@tLHdlPTd8ddtL||d8PtHpddHt|@hd|@d4dh(dX(hdhXT(dhpT80hdHX4(dlpTdxdtDlLlddxT|pd(ptXpddP4LxdLXDT@dhpT80dLptDxddxt|pdP@Dp0dhptx0d|0T4XdlpTdxdxpt(PdhHD8(d4TlL|dhHDx(d@hD@(dddL|lhtph40dhpTxPdlp4dXdhDDxldpxD08dh(dX(dHlTxTdd|ll4d40t|Xdh0480ht@hT@dhptXphdHxT(dh(D8Hd4PT|8dhpt8pd88dhXddDl|LhxdHHtddPtlXd|pt4Xdd0Tl8d0(D0hdhhd8hdppd0@ddPTlXd8P4hpdhlTx4d8dDhLdd@TLhhllplTddXT|0dH|4XDdh|4xDht8XD8ddptl8dH8d88dd|LLTdh(DXhddHt|@hpXhp(dhdDxLdDhT|@dhP4X0dXhDHhdh0T8Pd((dxhdhhDx(hdx8Txddp4LXd8xDH8dhPTXpdlPtD8dh(DxHd@8D@Xdhl48Td00Dp@dhLT8Tdp(d0(dhhd8(d404|8dhhdx(dx0T(pdd|lL4ddXt|Pdd0TlXhxdH(4ddllLDhhLXX|dhXDx8hl8hLxdhpT80dLPtDXdhptX0dPXd0XddP4lxd0@DpPdlptd8dl(dTPdhxDx8d(ptX0dhpT80htxxdXdhhDxhdXltHtddh4|@d@|dPTdhdDXLhpph0Pdhp48Pdt4lL|dh04xpdLpTD8dd@4lhdl8dt@ddhT|@dPxDp8dd04lXd40t|xdd0TLxdTdlLLddpTLXd|pTT8dd04lxhhH8XxdhddxlhddPT|dd04LXdlhd4pdh8d8xhh|8XLdhxd8xd(8d8xdhp48pd(8DX8dhhDXHd4dllLddx4|0d8PTH0ddPtlxd|P44XdlpTdxd(XDXXddpTlxdHltX4dhLTxtd|HDD0

ハッシュ関数は、高次ビットが低次ビットに影響を与えないように構築されているため、すべてのx低次ビットがゼロである文字列のコレクションを生成でき、これらの文字列の連結された組み合わせを試して、下位ビットはゼロなどです。これを破る方法が他にもあると確信しています。また、文字列を大幅に短くする方法もありますが、この方法では多くの数学を避けました。


驚くばかり!どちらも0x0000000a0000000a0000000a0000000a私のシステム上でハッシュしますが、それでもかなり素晴らしいです。(echo -ne '\x0a' |./hash同じ結果が得られます。)
r3mainer

1
@squeamishossifrage各文字列の後には単純なゼロである、それ以外の改行があります。
aaaaaaaaaaaa

そうそう、私の間違い:
r3mainer

4

Python 3、118バイト

int(H("9"+"0"*400))

そして

int(H("9"+"0"*4000))

(つまり:9E400および9E4000)

両方が生産する

83909358607540647658718900164058931893

少し掘り下げてみると、k> 128および(k%4 == 0)が同じハッシュを返すように、整数の後にkが繰り返される数字が続くようです。たとえば、H("1"+"1"*32*4)H("1"+"1"*33*4)は両方13493430891393332689861502800964084413です。うーん、128 ...


4

Python 2、161バイト、Puzzled

340282366920938463463374607431768211456 (decimal)
100000000000000000000000000000000 (hexadecimal)

そして

340282366920938468780317283222139437056 (decimal)
100000000000001203B66F94300000000 (hexadecimal)

両方とも出力があります:

83F172CC3D050D131F64FD04B8181DC2

数値は2 ^ 128および2 ^ 128 +(3 * 5 * 7 * 11 * 13 * 17)^ 2 * 19 * 2 ^ 32です。


3

Java、SuperJedi224による299バイト

のペーストビンMバイナリでMは、65535 1秒で、その後に2 0秒が続きます。

のペーストビンNバイナリでNは、21845 1秒で、その後に174766 0秒が続きます。

両方とも収穫し0ます。

アルゴリズムの基礎はi.bitCount()*i.bitLength()+1、最終的には結果をimod 2 128の累乗とし、mod 2 128にすることに注意してください。したがって、アイデアはi4で割り切れる2つを見つけることでしたが、最初の式は2 32を与えます。それは2 32を因数分解することで簡単にできました。 -1を、1のカウントと数値の合計ビット幅の2つの要因を選択。

編集:実際には、Mゼロが得られる理由にはもう少しありますが、2 32 -1の他の要因を使用して、最後に少なくとも64のゼロがあるように説明することで、ゼロをもたらすより多くの数字を簡単に見つけることができます。



3

C、87バイト

$ echo B075343F9832CD60 | ./hash6_ ; echo
fc2e9f02bd284bd1
$ echo 5914BD1B71164C77 | ./hash6_ ; echo
fc2e9f02bd284bd1

衝突ブルートフォーサーを使用して発見されました。


たぶん64ビットだからだろう。
Vi。

よくやった:-)どれくらいかかった?
r3mainer

プログラムを実行して約7分。さあ、測定を始めました。
Vi。

1
別の衝突が見つかりました:473E0B6ED5AF2B92 7EC2BC9B5E9F5645 -> 0000000000000000 0EAC34C8A9F943893525078917ハッシュ関数呼び出しとreal 14m24.970s user 48m42.410s時間の後。
Vi。

3

Python 2、115バイト、squeamish ossifrageによる

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

そして

2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

ハッシュ値はブロックの順序とは関係ありませんでした。



2

C ++、SpelingMistakeによる239バイト

提供された「メイン」プログラムを使用して、次の2つの入力は同じハッシュを生成します。

echo -n "dog" | ./h
481c27f26cba06cf

そして

echo -n "fog" | ./h
481c27f26cba06cf

コードのこのバグのため、入力最初の8バイトは処理されません

 for(I i=n;--i;) // and then we use q[i] for this iteration

なぜなら、(最初の8バイト:が)の--i場合にfalse と評価されるためです。ループ条件を置き換えると、これが修正されます。i==1q[0]Iint64for(I i=n;i--;)


入力の最初の8バイトは無視されるようです。
Vi。

コードのバグのようです。修正はプレフィックスではなくサフィックスになります。
tucuxi

1
バグではないコリジョンもあります(元の質問へのコメントを参照)。
Vi。

2

ルビー、90バイト、MegaTom

4271974071841820164790043412339104229205409044713305539894083215644439451561281100045924173873152

そして

23495857395130010906345238767865073260629749745923180469417457686044416983587046050252582956302336

2と11の後に40個のゼロバイトが続きます。したがって、どちらも41バイトです。ハッシュ値は各バイトの入力長によって追加され、その後10進数で逆になります。で終わる入力長1は、ハッシュ値がで終わることを確認できます0かなり早くます。それを逆にすると、ハッシュ値の長さが1減ります。

両方ともハッシュ値を持っています259


2

C#-393バイト-by:Logan Dam

70776e65642062792031333337206861786f7270776e65642062792031333337206861786f7200の両方のハッシュ18E1C8E645F1BBD1


涼しい!どうやってそれをクラックしたのか説明してもらえますか?そして、おそらく「不正なパディング」?
ldam

@LoganDam入力を切り替えるコードはすべて8文字の倍数を処理することになり、入力長が8の倍数でない場合はゼロに置き換えます。適切な場所にいくつかのゼロを追加すると、それらは単にパディングの場所になります。最初はゼロでした。
aaaaaaaaaaaa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.