暗号ハッシュゴルフ


34

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

チャレンジの性質により、警官のチャレンジは、関連する強盗のチャレンジへの関心が減少した場合、はるかに簡単になります。したがって、ハッシュ関数を投稿することはできますが、回答は受け入れられず、リーダーボードの一部にもなりません。

この課題は、最短の実装のために検索されたハッシュ関数衝突耐性、すなわち、同じハッシュを持つ2つの異なるメッセージを見つけるために実行不可能でなければなりません。

警官として、あなたはコードサイズと衝突抵抗の間の最良の妥協点を見つけるハッシュ関数を発明して実装しようとします。あまりにも多くのバイトを使用すると、別の警官があなたを追い出します!

強盗として、あなたは警官の機能をクラックすることで警官の試みを阻止しようとし、それらが不適切であることを証明します。これにより、アルゴリズムを強化するためにより多くのバイトが使用されるようになります!

警官の挑戦

仕事

暗号化ハッシュ関数H:I-> Oを選択して実装します。ここで、Iは2 2 30未満のすべての非負整数のセットであり、Oは2 128未満のすべての非負整数のセットです。

Hは、単一の整数、整数または整数の配列の文字列表現、またはSTDINから読み取り10進数または16進数でSTDOUTに出力する完全なプログラムを受け入れて返す実際の関数として実装できます。

得点

  • Hそれは抵抗するがあることを強盗は挑戦以下に定義します。

    強盗が投稿後最初の168時間以内にあなたの投稿を無効にすると、クラックされたと見なさます。

  • Hの実装はできるだけ短くする必要があります。最短のクラックされていない提出物が警官チャレンジの勝者になります。

追加のルール

  • Hを関数として実装する場合、上で説明したように動作するプログラム内から関数を実行するラッパーを提供してください。

  • プログラムまたはラッパーに少なくとも3つのテストベクトルを入力してください(入力例と対応する出力)。

  • Hは、自分で実装する限り、新しい設計(推奨)または既知のアルゴリズムにすることができます。あらゆる種類の組み込みハッシュ関数、圧縮関数、暗号、PRNGなどを使用することは禁じられています。

    ハッシュ関数(たとえば、ベース変換)を実装するために一般的に使用されるすべての組み込みは、公正なゲームです。

  • プログラムまたは関数の出力は確定的でなければなりません。

  • x86またはx64プラットフォーム上で、またはWebブラウザー内から実行できる無料の(ビールのように)コンパイラー/インタープリターが必要です。

  • プログラムまたは関数は合理的に効率的で、2 2 19未満のIのメッセージを1秒未満でハッシュする必要があります。

    エッジケースの場合、私のマシン(Intel Core i7-3770、16 GiBのRAM)にかかる(壁の)時間は決定的になります。

  • この課題の性質を考えると、出力を変更するかどうかにかかわらず、回答のコードを何らかの方法で変更することは禁止されています。

    提出物がクラックされている場合(または、クラックされていない場合でも)、追加の回答を投稿できます。

    回答が無効な場合(たとえば、I / O仕様に準拠していない場合)、削除してください。

Python 2.7、22バイト

def H(M):
 return M%17

ラッパー

print H(int(input()))

強盗チャレンジ

仕事

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

得点

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

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

追加のルール

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

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

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

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

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

Python 2.7、user8675309による22バイト

1

そして

18

リーダーボード

安全な提出

  1. CJam、eBusinessによる21バイト
  2. C ++、tucuxiによる148バイト
  3. C ++、Viによる233(?)バイト。

クラックされていない提出

このStack Snippetを使用して、まだクラックされていない回答のリストを取得できます。

function g(p){$.getJSON('//api.stackexchange.com/2.2/questions/51068/answers?page='+p+'&pagesize=100&order=desc&sort=creation&site=codegolf&filter=!.Fjs-H6J36w0DtV5A_ZMzR7bRqt1e',function(s){s.items.map(function(a){var h=$('<div/>').html(a.body).children().first().text();if(!/cracked/i.test(h)&&(typeof a.comments=='undefined'||a.comments.filter(function(b){var c=$('<div/>').html(b.body);return /^cracked/i.test(c.text())||c.find('a').filter(function(){return /cracked/i.test($(this).text())}).length>0}).length==0)){var m=/^\s*((?:[^,(\s]|\s+[^-,(\s])+)\s*(?:[,(]|\s-).*?([0-9]+)/.exec(h);$('<tr/>').append($('<td/>').append($('<a/>').text(m?m[1]:h).attr('href',a.link)),$('<td class="score"/>').text(m?m[2]:'?'),$('<td/>').append($('<a/>').text(a.owner.display_name).attr('href',a.owner.link))).appendTo('#listcontent');}});if(s.length==100)g(p+1);});}g(1);
table th, table td {padding: 5px} th {text-align: left} .score {text-align: right} table a {display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><table><tr><th>Language</th><th class="score">Length</th><th>User</th></tr><tbody id="listcontent"></tbody></table>


ハッシュ関数が誤って2 ^ 128-1より大きい数値を返す場合、それは送信を無効にしますか、または単に2 ^ 128を法とする結果を取得しますか?
マーティンエンダー

@MartinBüttner:はい、2 ^ 128を法として結果を取得する必要があります。
デニス

1
@Scimonsterは要件を満たしていません(最大2 ^ 30ビットの入力、128ビットの出力)
CodesInChaos

1
警官や強盗は通常、逆のことをしませんか?
ハネフムバラク

2
おそらく、提出にはハッシュの例を含める必要があるというルールがあります。実装をクラックするものと比較する結果を得るために、選択したプログラミング言語の提出者を実行しなければならないことは非常に面倒です。
aaaaaaaaaaaa

回答:


6

CJam、21バイト

1q3*{i+_E_#*^26_#)%}/

入力としてバイトの文字列を受け取ります。

擬似コードで:

hash = 1
3 times:
    for i in input:
        hash = hash + i
        hash = hash xor hash * 14^14
        hash = hash mod (26^26 + 1)
output hash

ハッシュの例:

""(空の文字列)-> 1
"テスト"-> 2607833638733409808360080023081587841
"テスト"-> 363640467424586895504738713637444713

単純な面では少しかもしれませんが、出力範囲は122ビットを少し超えているだけです。トリプル反復の強化は、毎回まったく同じことを行うため、すでに少し壊れています。反復は完全に中断されます。しかし、それは短く、安全すぎるのは楽しいことではありません。


他のCJamの投稿のような付随するCバージョンはありますか?
Vi。

@Vi。いいえ、少なくともまだ。Cでbigintに手を出したことがありません。そのための標準ライブラリはありますか?
aaaaaaaaaaaa

GMP
Vi。


1
@ Agawa001用語が混同されています。これは、トリプルパススポンジ関数ハッシュアルゴリズムです。シーザー暗号は、内部状態のない特定の暗号化アルゴリズムです。
aaaaaaaaaaaa

7

Python、109バイト[ ひび割れそして再び ]

def f(n,h=42,m=2**128):
 while n:h+=n&~-m;n>>=128;h+=h<<10;h^=h>>6;h%=m
 h+=h<<3;h^=h>>11;h+=h<<15;return h%m

Jenkinsの一度に1つの関数をそのまま実装しようとしましたが、唯一の違いはシードとビット数です。

楽しい事実:どうやらPerlはある時点でJenkinsのハッシュを使用したようです。

ラッパー

print(f(int(input())))

>>> f(0)
12386682
>>> f(1)
13184902071
>>> f(2**128-1)
132946164914354994014709093274101144634
>>> f(2**128)
13002544814292
>>> f(2**128+1)
13337372262951
>>> f(2**(2**20))
290510273231835581372700072767153076167



6

C ++、148バイト

typedef __uint128_t U;U h(char*b,U n,U&o){U a=0x243f6a8885a308d,p=0x100000001b3;for(o=a;n--;)for(U i=27;--i;){o=(o<<i)|(o>>(128-i));o*=p;o^=b[n];}}

__uint128_tはGCC拡張機能であり、期待どおりに機能します。ハッシュは、各反復の開始時にsha1のように回転するFNVハッシュの反復(a16進数ではPiの最初の桁ですが、その素数を借りました)に基づいています。でコンパイルすると、10MBのファイルをハッシュするのに2秒もかかりません。そのため、内側のループの反復を増やす余地はまだありますが、今日は寛大に感じています。-O3

クラッキングの楽しみのために、非修飾(変数名の変更、コメントの追加、空白、および中括弧のペア):

typedef __uint128_t U;
U h(char* input, U inputLength, U &output){
    U a=0x243f6a8885a308d,p=0x100000001b3;    
    for(output=a;inputLength--;) {   // initialize output, consume input
        for(U i=27;--i;) {                          // evil inner loop
            output = (output<<i)|(output>>(128-i)); // variable roll 
            output *= p;                            // FNV hash steps
            output ^= input[inputLength];        
        }
    }
    // computed hash now available in output
}

ゴルフの提案は大歓迎です(それらに基づいてコードを改善することができなくても)。

編集:修正されたコードの誤字を修正しました(ゴルフバージョンは変更されていません)。


o初期化されていないようです。どこoutputで宣言されていますか?それともoありますかoutput
Vi。

についても同じですn。実行するために「非uglified」コードを実際にチェックしましたか?
Vi。

ブルートフォーサーを開始しました...
Vi。

3ラウンドバージョンでも簡単ではありません。
Vi。

@Vi。修正されていないバージョンを修正しました-良くチェックしていないのが残念です。私はその内側のループを誇りに思っています。U i=81;i-=3実行時のコストを大幅に削減することなく、さらに厄介だったかもしれません。
tucuxi

5

CJam、44バイト[ クラック ]

lW%600/_z]{JfbDbGK#%GC#[md\]}%z~Bb4G#%\+GC#b

入力は基数10です。

CJamは遅いです。一部のコンピューターで1秒で実行されることを望みます...

説明

lW%600/            e# Reverse, and split into chunks with size 600.
_z                 e# Duplicate and swap the two dimensions.
]{                 e# For both versions or the array:
    JfbDb          e# Sum of S[i][j]*13^i*19^j, where S is the character values,
                   e# and the indices are from right to left, starting at 0.
    GK#%GC#[md\]   e# Get the last 32+48 bits.
}%
z~                 e# Say the results are A, B, C, D, where A and C are 32 bits.
Bb4G#%             e# E = the last 32 bits of A * 11 + C.
\+GC#b             e# Output E, B, D concatenated in binary.

さて、2次元のものは弱点のように見えました...最初は遅い計算をより速くすることを目的としていました。しかし、私が何をしても、すぐに実行することはできないので、最後に遅いコードを削除しました。

バイナリビット以上の基数を使用した場合も良いはずです。

Cバージョン

__uint128_t hash(unsigned char* s){
    __uint128_t a=0,b=0;
    __uint128_t ar=0;
    __uint128_t v[600];
    int l=0,j=strlen(s);
    memset(v,0,sizeof v);
    for(int i=0;i<j;i++){
        if(i%600)
            ar*=19;
        else{
            a=(a+ar)*13;
            ar=0;
        }
        if(i%600>l)
            l=i%600;
        v[i%600]=v[i%600]*19+s[j-i-1];
        ar+=s[j-i-1];
    }
    for(int i=0;i<=l;i++)
        b=b*13+v[i];
    a+=ar;
    return (((a>>48)*11+(b>>48))<<96)
        +((a&0xffffffffffffull)<<48)
        +(b&0xffffffffffffull);
}

説明を追加してください。誰もがCJamを知っているわけではありません。
orlp

@orlp編集
...-jimmy23013

私のコンピューターでは0.4秒かかりますので、許容範囲内です。
デニス

A、B、Cなどとは何ですか?いくつかのマトリックス?どの次元ですか?Cで簡単に実装できますか?
Vi。

1
割れた、私は信じています。
Sp3000

5

C ++、182文字(+約51文字の定型文)

h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=buf[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}

定型文:

void hash(const unsigned char* buf, size_t len, unsigned long long *hash1, unsigned long long *hash2)
{
    unsigned long long &h=*hash1;
    unsigned long long &j=*hash2;
    size_t l = len;
    const unsigned char* b = buf;

    // code here
}

ゴルフ機能付きの実行可能なプログラム

#include <stdio.h>

// The next line is 227 characters long
int hash(char*b,int l,long long&h,long long&j){h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=b[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}}

int main() {
    char buf[1024];
    int l  = fread(buf, 1, 1024, stdin);
    long long q, w;
    hash(buf, l, q, w);
    printf("%016llX%016llX\n", q, w);
}

2
関数宣言などは文字数にカウントされると思います。
Ypnypn

@Ypnypn、ゴルフダウンされた関数宣言で文字をカウントしました。
Vi。

出力ハッシュとは何ですか?私はそれが((h << 64)| j)であると仮定しています。
tucuxi

はい。または、64ビットの数字のペア。私は__uint128_tこれを実装した後にのみ知りました。
Vi。

1
@Dennis、Done.󠀠
Viに。

4

Pyth、8 クラック

sv_`.lhQ

オンラインで試す

少しばかげた答えですが、ほとんどの人はPythを読むことができないため、どのように機能するかを説明します。これは、1の自然対数と入力を取り、それを文字列に変換します。その文字列は反転され、評価されてから整数に変換されます。

Pythonの翻訳は次のようになります。

import math
n = eval(input()) + 1
rev = str(math.log(n))[::-1]
print(int(eval(rev)))


4

Python 3、216バイト[ クラック ]

def f(m):
 h=1;p=[2]+[n for n in range(2,102)if 2**n%n==2];l=len(bin(m))-2;*b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])
 while b:
  h*=h
  for P in p:
   if b:h=h*P**b.pop()%0xb6ee45a9012d1718f626305a971e6a21
 return h

仕様との非互換性のために、少なくとも1 つのわずかな脆弱性を考えることができますが、それ以外は、これは少なくともブルートフォースの証拠だと思います。とりわけ、最初の1,000万ハッシュをチェックしました。

ゴルフに関しては、これはPython 2の方が短くなりますが、効率のためにいくつかのバイトを犠牲にしました(とにかく勝つつもりはないので)。

編集:これは非常にスムーズなハッシュを実装する私の試みでしたが、残念ながら128ビットはあまりにも小さすぎました。

ラッパー

print(f(int(input())))

>>> f(0)
2
>>> f(123456789)
228513724611896947508835241717884330242
>>> f(2**(2**19)-1)
186113086034861070379984115740337348649
>>> f(2**(2**19))
1336078

コードの説明

def f(m):
 h=1                                             # Start hash at 1
 p=[2]+[n for n in range(2,102)if 2**n%n==2]     # p = primes from 2 to 101
 l=len(bin(m))-2                                 # l = bit-length of m (input)
 *b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])      # Convert bits to list, padding to
                                                 # a multiple of 26 then adding the
                                                 # bit-length at the front

 while b:                                        # For each round
  h*=h                                           # Square the hash
  for P in p:                                    # For each prime in 2 ... 101
   if b:h=(h*P**b.pop()                          # Multiply by prime^bit, popping
                                                 # the bit from the back of the list
           %0xb6ee45a9012d1718f626305a971e6a21)  # Take mod large number

 return h                                        # Return hash

次のパディングの例f(6)

[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]

(len 3)(------------------ 23 zeroes for padding -------------------------)(input 6)
       (---------------------------- length 26 total ------------------------------)


4

C、87バイト[ クラック ]

これは完全なプログラムです。ラッパーは必要ありません。stdin経由のバイナリ入力を受け入れ、16進数のハッシュをstdoutに出力します。

c;p;q;main(){while((c=getchar())+1)p=p*'foo+'+q+c,q=q*'bar/'+p;printf("%08x%08x",p,q);}

これは64ビットハッシュのみを計算するため、ここでは少しギャンブルをしています。

疑問に思う人のために、2つの定数'foo+''bar/'は素数1718578987と1650553391です。


例:

先行ゼロを無視します。

echo -ne '\x00\x00\x00\x00' |./hash
0000000000000000

シングルバイト入力:

echo -ne '\x01' |./hash
0000000100000001
echo -ne '\xff' |./hash
000000ff000000ff

マルチバイト入力:

echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15c
echo -ne 'Hello, World' |./hash
04f1a7412b17b86c

「aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa」
イスマエルミゲル

1
foo|(d5c9bef71d4f5d1b)及びfoo\(d5c9bef71d4f5d1b)が生じる非常に類似したハッシュ。
イスマエルミゲル

1
壊した!!! \x00そして\x00\x00
イスマエルミゲル

1
チャットのコメントに基づいて、これはまだクラックされていないと思いますか?重複したコメントは、クラックされていないハッシュをスキミングしている人にとって混乱を招く可能性があるため、ダブルチェックだけです。
Sp3000


3

J-39バイト- クラック

入力として文字列を取り、<2 128の整数を返す関数。有効にするために関数に名前を付ける必要があると仮定しているため、匿名関数を送信できる場合は、カウントからさらに3文字を削除します。

H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]

象形文字を読まない人のために、私がやっていることの要約を以下に示します。

  • a=.(2^128x)&|@^/@これはサブルーチン*であり、数値の配列を受け取り、累乗がmod 2 128で行われるパワータワーとして扱います。「パワータワー」とは、入力した3 4 5 6場合、計算されることを意味します3 ^ (4 ^ (5 ^ 6))
  • (".p:@+5,9:)aこの関数は文字列を取り、それを数値Nに変換し、(n +5)番目と(n +9)番目の素数を計算してaから、その上からfromをスローします。つまり、p(n+5) ^ p(n+9)mod 2 128を見つけます。ここp(k)ではk-番目の素数です。
  • H=:_8...\(a...)]入力の8文字のサブブロックで上記の関数を実行し、aすべての結果をまとめて、結果のハッシュ関数を呼び出しますH。Jの「k-th prime」関数がp(k)2 31を超えると失敗する、つまりk=105097564最も安全であるため、8文字を使用しますk

サンプル出力があります。これはtryj.tkでオンラインで試すことができますが、Jsoftwareからインタープリターをダウンロードして自宅で行うことをお勧めします。

   H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]
   H '88'
278718804776827770823441490977679256075
   H '0'
201538126434611150798503956371773
   H '1'
139288917338851014461418017489467720433
   H '2'
286827977638262502014244740270529967555
   H '3'
295470173585320512295453937212042446551
   30$'0123456789'  NB. a 30 character string
012345678901234567890123456789
   H 30$'0123456789'
75387099856019963684383893584499026337
   H 80$'0123456789'
268423413606061336240992836334135810465

*技術的には、それ自体は機能ではなく、他の機能にアタッチしてその出力に作用します。ただし、これはJのセマンティックな問題であり、概念的な違いではありません。プログラムフローは上記で説明したとおりです。



2

Python 3、118バイト[ クラック ]

def H(I):
    o=0;n=3;M=1<<128
    for c in I:i=ord(c);o=(o<<i^o^i^n^0x9bb90058bcf52d3276a7bf07bcb279b7)%M;n=n*n%M
    return o

インデントは単一のタブです。単純なハッシュ、まだ完全にテストしていません。

次のように呼び出します。

print(H("123456789"))

結果: 73117705077050518159191803746489514685


入力整数は、アルゴリズムで使用する文字列にどのように変換する必要がありますか?
feersum

@feersum base-10文字列は、私がテストしたものです。それは何を使用しませんが、ord(c)しかし、そう本当に、:)行います任意の文字列(NUL文字のようなものを除いては、私は本当に簡単なものを作るのハッシュ衝突を考えるので、スティックを0-9文字列で。。)
tomsmeding

1
それを破った: codegolf.stackexchange.com/a/51160/41288を。「10000」や「20000」などの文字列が非常に近いハッシュを生成することを観察することから始めました。ますます多くのゼロで遊び始め、128かそこらの後、数字+ k * 4ゼロの繰り返しはkに関係なく同じハッシュを返します。
tucuxi

@tucuxiは、それがあまりにも難しくないはずだとすでに思っていました。それは簡単なことではありませんでしたが、誰かがとにかくそれを壊したことを嬉しく思います。よくできました。
-tomsmeding

2

C ++、239バイト

初めてのコードゴルフ![ 優しくしてください ]

#define r(a,b) ((a<<b)|(a>>(64-b)))
typedef uint64_t I;I f(I*q, I n, I&h){h=0;for(I i=n;--i;)h=r(h^(r(q[i]*0x87c37b91114253d5,31)*0x4cf5ad432745937f),31)*5+0x52dce729;h^=(h>>33)*0xff51afd7ed558ccd;h^=(h>>33)*0xc4ceb9fe1a85ec53;h^=(h>>33);}

ゴルフされていないバージョン:

I f(I* q, I n, I& h) // input, length and output
{
    h = 0; // initialize hashes
    for (I i=n;--i;)
    {
        q[i] *= 0x87c37b91114253d5;
        q[i]  = rotl(q[i], 31);
        q[i] *= 0x4cf5ad432745937f;

        h ^= q[i]; // merge the block with hash

        h *= rotl(h, 31);
        h = h * 5 + 0x52dce729;
    }
    h ^= h>>33;
    h *= 0xff51afd7ed558ccd;
    h ^= h>>33;
    h *= 0xc4ceb9fe1a85ec53; // avalanche!
    h ^= h>>33;
}

最良のハッシュではなく、間違いなく存在する最短のコードでもありません。ゴルフのヒントを受け入れ、改善を望んでいます!

ラッパー

おそらく世界最高ではありませんが、それでもラッパーです

I input[500];

int main()
{
    string s;
    getline(cin, s);
    memcpy(input, s.c_str(), s.length());
    I output;
    f(input, 500, output);
    cout << hex << output << endl;
}

2
しっかりしているように見えますが、64ビットでは、総当たり攻撃の対象になる場合があります。〜sqrt(n)テストで衝突を見つける可能性は約50%です(合計n個の出力の中から)。2 ^ 32回の試行は、現代のPCではそれほど多くありません。
tucuxi

ラッパーにはヘッダーのインクルードがなく、一般に多くの同等のハッシュになります。
Vi。

いくつかのハッシュサンプルを提供します。私にとっては、「3」と「33」の両方が481c27f26cba06cfになります(このラッパーを使用)。
Vi。

ひび割れ:codegolf.stackexchange.com/a/51215/41288。@Viの直前に疑っています。なぜこれほど多くのハッシュが等しいのかがわかりました。
tucuxi

1
適切な衝突(バグを使用しない):printf '33333333\x40\xF3\x32\xD6\x56\x91\xCA\x66' | ./hash7_-> a4baea17243177fd; printf '33333333\x77\x39\xF3\x82\x93\xDE\xA7\x2F' | ./hash7_-> a4baea17243177fd。ブルートフォーサーは、ここでの他の64ビットハッシュと比較して、ここでの衝突をはるかに速く見つけます。
Vi。

2

Java、299 291 282バイト、クラック。

import java.math.*;class H{public static void main(String[]a){BigInteger i=new java.util.Scanner(System.in).nextBigInteger();System.out.print(BigInteger.valueOf(i.bitCount()*i.bitLength()+1).add(i.mod(BigInteger.valueOf(Long.MAX_VALUE))).modPow(i,BigInteger.valueOf(2).pow(128)));}}

BigIntegerに対していくつかの操作を行い、結果をモジュロ2 128にします。


これを実行するにはどうすればよいですか?Ideoneはコンパイルを拒否します。
マーティンエンダー

1
Ideoneで実行するには、クラスの名前を「メイン」に変更するか、最初の「パブリック」キーワードを削除します(ただし、2番目のキーワードは削除しません)。どちらでも機能します。
SuperJedi224


1
@ SuperJedi224なぜpublic自分で最初の文字を削除して、7文字節約してみませんか?
user253751

@immibisそれは、Eclipseで正しく動作するとは思わないからです。でもやってみます。編集:そうだと思います。それは驚きです。
SuperJedi224

2

C、128バイト[ クラック ]

p;q;r;s;main(c){while((c=getchar())+1)p=p*'foo+'+s^c,q=q*'bar/'+p,r=r*'qux3'^q,s=s*'zipO'+p;printf("%08x%08x%08x%08x",p,q,r,s);}

これは、私の最後の努力 (Viによってクラックされました)とほぼ同じアルゴリズムですが適切な128ビットハッシュを生成するのに十分なハムスターホイールを備えています。

コード内の4つの主要な定数は次のとおりです。

'foo+' = 1718578987
'bar/' = 1650553391
'qux3' = 1903523891
'zipO' = 2053730383

前と同じように、これはラッパーを必要としない完全なプログラムです。整数Iは、stdinを介して生のバイナリデータ(ビッグエンディアン)として入力され、ハッシュOは16進数でstdoutに出力されます。Iの先行ゼロは無視されます。

例:

echo -ne '\x00' |./hash
00000000000000000000000000000000
echo -ne '\x00\x00' |./hash
00000000000000000000000000000000
echo -ne '\x01' |./hash
00000001000000010000000100000001
echo -ne 'A' |./hash
00000041000000410000004100000041
echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15cb9a5996fe0d8df7c
echo -ne 'Hello, World' |./hash
da0ba2857116440a9bee5bb70d58cd6a


あなたの例は、衝突(最初の2つ)を示していませんか?
mbomb007

@ mbomb007いいえ。入力は0〜2 ^(2 ^ 30)の数値です。0x00と0x0000は両方ともゼロに等しいため、同じ出力を生成します。
squeamish ossifrage

2

C、122バイト[ クラック ]

long long x,y,p;main(c){for(c=9;c|p%97;c=getchar()+1)for(++p;c--;)x=x*'[3QQ'+p,y^=x^=y^=c*x;printf("%016llx%016llx",x,y);}

ネストされたループ、ハーフアサートされたLCG、および変数スワッピング。愛してはいけないことは何ですか?

試してみるのは、次のバージョンです。

long long x,y,p;

int main(int c){
    // Start with a small number of iterations to
    //   get the state hashes good and mixed because initializing takes space
    // Then, until we reach the end of input (EOF+1 == 0)
    //   and a position that's a multiple of 97
    for (c=9;c|p%97;c=getchar()+1) {

        // For each input c(haracter) ASCII value, iterate down to zero
        for (++p;c--;) {

            // x will act like a LCG with a prime multiple
            //   partially affected by the current input position
            // The string '[3QQ' is the prime number 0x5B335151
            x=x*'[3QQ'+p;

            // Mix the result of x with the decrementing character
            y^=c*x;

            // Swap the x and y buffers
            y^=x^=y;
        }
    }

    // Full 128-bit output
    printf("%016llx%016llx",x,y);
    return 0;
}

これは、STDINから読み取り、STDOUTに出力する完全な自己完結型プログラムです。

例:

> echo -n "Hello world" | ./golfhash
b3faef341f70c5ad6eed4c33e1b55ca7

> echo -n "" | ./golfhash
69c761806803f70154a7f816eb3835fb

> echo -n "a" | ./golfhash
5f0e7e5303cfcc5ecb644cddc90547ed

> echo -n "c" | ./golfhash
e64e173ed4415f7dae81aae0137c47e5

いくつかの簡単なベンチマークでは、3MB / sのテキストデータをハッシュします。ハッシュ速度は入力データ自体に依存するため、おそらく考慮する必要があります。



1

PHP 4.1、66バイト[ クラック ]

ウォーミングアップ中です。

この興味をそそられることを願っています。

<?for($l=strlen($b.=$a*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

9999999999999999999999999999999
の数字を試してみました。出力は2 128の範囲内にあるようです。


register_globalsディレクティブのため、PHP 4.1が必要です。

セッション、POST、GET、REQUEST、Cookieからローカル変数を自動的に作成することで機能します。

キーを使用しますa。(例:アクセスhttp://localhost/file.php?a=<number>)。

PHP 4.2以降でテストしたい場合は、これを試してください:

<?for($l=strlen($b.=$a=$_REQUEST['a']*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

このバージョンは、POSTおよびGETでのみ機能します。


出力例:

0 -> 0000000000000000000000000000000000000000
9 -> 8111111111111111111111111111111111111111
9999 -> 8888111111111111111111111111111111111111
1234567890 -> 0325476981111111111111111111111111111111
99999999999999999999999999999999999999999999999999999999999999999999999999999999 -> 0111191111111111111111111111111111111111

(同じハッシュを生成する数字があることを保証します)。



1

C、134バイト、クラック

これは完全なCプログラムです。

long long i=0,a=0,e=1,v,r;main(){for(;i++<323228500;r=(e?(scanf("%c",&v),e=v>'/'&&v<':',v):(a=(a+1)*7)*(7+r)));printf("0x%llx\n", r);}

仕組み:入力をバイト配列として受け取り、最後に擬似ランダム(ただし確定的)バイトを追加して、長さを約2 2 30(もう少し)にします。実装は、バイトごとに入力を読み取り、数字ではない最初の文字を見つけると、擬似ランダムデータの使用を開始します。

組み込みPRNGは許可されていないため、自分で実装しました。

コードを短くする未定義/実装定義の動作があります(最終値は符号なしであり、値ごとに異なる型を使用する必要があります)。Cでは128ビット値を使用できませんでした。難読化されていないバージョン:

long long i = 0, prand = 0, notEndOfInput = 1, in, hash;

main() {
    for (; i++ < 323228500;) {
        if (notEndOfInput) {
            scanf("%c", &in);
            notEndOfInput = in >= '0' && in <= '9';
            hash = in;
        } else {
            prand = (prand + 1)*7;
            hash = prand*(7 + hash);
        }
    }
    printf("0x%llx\n", hash);
}


1

Python 2.X-139バイト [[ ひび割れ ]]

これは、他のすべての(LOOP、XOR、SHIFT、ADD)ハッシュと非常によく似ています。あなたのポイント強盗を手に入れてください;)これが解決された後、私はより難しいものを作ります。

M=2**128
def H(I):
 A=[1337,8917,14491,71917];O=M-I%M
 for z in range(73):
  O^=A[z%4]**(9+I%9);O>>=3;O+=9+I**(A[z%4]%A[O%4]);O%=M
 return O

ラッパー(16進数とも呼ばれる16進数の引数が1つ必要です):

import sys
if __name__ == '__main__':
 print hex(H(long(sys.argv[1], 16)))[2:][:-1].upper()


1
また、私のマシンでは大きな入力で関数が数秒かかるため、このエントリがOPの仕様を満たしているかどうかはわかりません。例えば、H(2**(2**10))一方で、約8または9秒を要したH(2**(2**12))の周りに29秒かかりましたし、H(2**(2**14))2分を引き継ぎました。
mathmandan

あなたは絶対に正しいです、私は明らかに大きな入力のタイミングをテストする必要がありました。また、そのシフトが追加された後、自分でテストを実行するのを忘れていたようです。元のバージョンはシフトせず(投稿前)、「最初の100000整数で衝突なし」テストに合格していました:/
困惑

1

Python 2.7-161バイト[[ ひび割れ ]]

まあ、最初のハッシュ関数を投稿する前に役に立たないバージョンに変更することができたので、同様の構造の別のバージョンを投稿すると思います。今回は、ささいな衝突に対してテストし、速度について考えられるほとんどの入力の大きさをテストしました。

A=2**128;B=[3,5,7,11,13,17,19]
def H(i):
 o=i/A
 for r in range(9+B[i%7]):
  v=B[i%7];i=(i+o)/2;o=o>>v|o<<128-v;o+=(9+o%6)**B[r%6];o^=i%(B[r%6]*v);o%=A
 return o

ラッパー(バイトカウントにはカウントされません)

import sys
if __name__ == '__main__':
 arg = long(sys.argv[1].strip(), 16)
 print hex(H(arg))[2:][:-1].upper()

実行例(入力は常に16進数):

$ python crypt2.py 1
3984F42BC8371703DB8614A78581A167
$ python crypt2.py 10
589F1156882C1EA197597C9BF95B9D78
$ python crypt2.py 100
335920C70837FAF2905657F85CBC6FEA
$ python crypt2.py 1000
B2686CA7CAD9FC323ABF9BD695E8B013
$ python crypt2.py 1000AAAA
8B8959B3DB0906CE440CD44CC62B52DB


よくやったジミー:)
秒で困惑

1

ルビー、90バイト

def H(s);i=823542;s.each_byte{|x|i=(i*(x+1)+s.length).to_s.reverse.to_i%(2**128)};i;end

実際のハッシュを見ずに作成した非常にランダムなハッシュアルゴリズム...それが良いかどうかはわかりません。入力として文字列を受け取ります。

ラッパー:

def buildString(i)
  if(i>255)
    buildString(i/256)+(i%256).chr
  else
    i.chr
  end
end 
puts H buildString gets

質問に必要なラッパーを提供してください。
デニス

入力形式は何ですか?私は数字で試しましたが、それは言いcomparison of String with 255 failed (ArgumentError)ます。
jimmy23013

Hは文字列を受け取り、Build stringはOPが必要とする数を受け取り、それを文字列に変換します。
メガトム

gets.to_iラッパーにが必要だと思います。
jimmy23013


0

Mathematica、89バイト、クラック

Last@CellularAutomaton[(a=Mod)[#^2,256],{#~IntegerDigits~2,0},{#~a~99,128}]~FromDigits~2&

最短ではありません。


3
Mathematicaなしでこれをどのように実行しますか?「x86またはx64プラットフォーム上で、またはWebブラウザー内から実行できる無料の(ビールのように)コンパイラー/インタープリターが必要です。」
マーティンエンダー

2
@MartinBüttnerwolfram.com/mathematica/ trial
LegionMammal978


0

PHP、79バイト(クラック。コメント付き):

echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);

これは、PHPでの型変換によって多くの恐ろしいことを行うため、予測が困難になります;)(または少なくともそうすることを期待しています)ただし、これは最短または最も読めない答えではありません。

これを実行するには、PHP4を使用してグローバルを登録(?i = 123を使用)するか、コマンドラインを使用します。

php -r "$i = 123.45; echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);"

5
ハッシュの出力値は浮動小数点に見えます。そして、それは3000000000000000000000000000000000000000000001と3000000000000000000000000000000000000000000000.に同じだ
Viに。

0

C#-393バイトのクラック

using System;class P{static void Main(string[]a){int l=a[0].Length;l=l%8==0?l/8:l/8+1;var b=new byte[l][];for(int i=0;i<l;i++){b[i]=new byte[8];};int j=l-1,k=7;for(int i=0;i<a[0].Length;i++){b[j][k]=Convert.ToByte(""+a[0][i],16);k--;if((i+1)%8==0){j--;k=7;}}var c=0xcbf29ce484222325;for(int i=0;i<l;i++){for(int o=0;o<8;o++){c^=b[i][o];c*=0x100000001b3;}}Console.WriteLine(c.ToString("X"));}}

ゴルフをしていない:

using System;
class P
{
    static void Main(string[]a)
    {
      int l = a[0].Length;
      l = l % 8 == 0 ? l / 8 : l / 8 + 1;
      var b = new byte[l][];
      for (int i = 0; i < l; i++) { b[i] = new byte[8]; };
      int j = l-1, k = 7;
      for (int i = 0; i < a[0].Length; i++)
      {
        b[j][k] = Convert.ToByte(""+a[0][i], 16);
        k--;
        if((i+1) % 8 == 0)
        {
          j--;
          k = 7;
        }
      }
      var c = 0xcbf29ce484222325;
      for (int i = 0; i < l; i++)
      {
        for (int o = 0; o < 8; o++)
        {
          c ^= b[i][o];
          c *= 0x100000001b3;
        }
      }
      Console.WriteLine(c.ToString("X"));
    }
}

私はこれまでに暗号やハッシュに触れたことがないので、優しくしてください:)

これは、入力でピボットする配列を持つFNV-1aハッシュの単純な実装です。これを行うより良い方法があると確信していますが、これは私ができる最善の方法です。

長い入力では少しのメモリを使用する場合があります。


クラック:codegolf.stackexchange.com/a/51277/101パディングに問題があることに加えて、これは暗号化ハッシュではなく、それを破る方法はたくさんあります。
aaaaaaaaaaaa

0

Python 2、115バイト[ 既にクラック済み!]

OK、最後の努力です。最後の改行は必要ないため、115バイトのみです。

h,m,s=1,0,raw_input()
for c in[9+int(s[x:x+197])for x in range(0,len(s),197)]:h+=pow(c,257,99**99+52)
print h%4**64

これは、stdinに10進整数を入力し、stdoutに10進ハッシュ値を出力する完全なプログラムです。余分な先行ゼロは異なるハッシュ値になりますので、入力には何もないと仮定します。

これは、197桁の入力数値のチャンクをモジュラー累乗法で詰めることで機能します。一部の言語とは異なり、int()関数のデフォルトは常に基数10なのでint('077')、63ではなく77です。

サンプル出力:

$ python hash.py <<<"0"
340076608891873865874583117084537586383

$ python hash.py <<<"1"
113151740989667135385395820806955292270

$ python hash.py <<<"2"
306634563913148482696255393435459032089

$ python hash.py <<<"42"
321865481646913829448911631298776772679

$ time python hash.py <<<`python <<<"print 2**(2**19)"`
233526113491758434358093601138224122227

real    0m0.890s   <-- (Close, but fast enough)
user    0m0.860s
sys     0m0.027s

1
これは、ブロックの順序...使用していませんでしたひび割れを
jimmy23013

あー 私が与える:-(
squeamish ossifrage
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.