Golf hash kriptografis


34

Kontes ini sudah berakhir.

Karena sifat tantangan , tantangan polisi menjadi jauh lebih mudah ketika minat terhadap tantangan perampok terkait berkurang. Karena itu, selagi Anda masih dapat memposting fungsi hash, jawaban Anda tidak akan diterima atau menjadi bagian dari papan peringkat.

Tantangan ini adalah pencarian implementasi terpendek dari fungsi hash yang tahan benturan , yaitu, tidak mungkin menemukan dua pesan berbeda dengan hash yang sama.

Sebagai seorang polisi, Anda mencoba untuk menciptakan dan mengimplementasikan fungsi hash menemukan kompromi terbaik antara ukuran kode dan resistensi tabrakan. Gunakan terlalu banyak byte dan polisi lain akan mengalahkan Anda!

Sebagai seorang perampok, Anda mencoba menggagalkan upaya polisi dengan merusak fungsinya, membuktikan bahwa itu tidak sesuai. Ini akan memaksa mereka menggunakan lebih banyak byte untuk memperkuat algoritme mereka!

Tantangan polisi

Tugas

Menerapkan fungsi hash kriptografis H: I -> O pilihan Anda, di mana saya adalah himpunan semua bilangan bulat non-negatif di bawah 2 2 30 dan O adalah himpunan semua bilangan bulat non-negatif di bawah 2 128 .

Anda dapat mengimplementasikan H sebagai fungsi aktual yang menerima dan mengembalikan integer tunggal, representasi string integer atau array integer atau program lengkap yang membaca dari STDIN dan mencetak ke STDOUT di basis 10 atau 16.

Mencetak gol

  • H bahwa ia harus menolak tantangan perampok yang didefinisikan di bawah ini.

    Jika seorang perampok mengalahkan kiriman Anda dalam 168 jam pertama setelah mempostingnya, itu dianggap retak .

  • Implementasi H harus sesingkat mungkin. Pengajuan terputus terpendek akan menjadi pemenang dari tantangan polisi.

Aturan tambahan

  • Jika Anda menerapkan H sebagai fungsi, berikan pembungkus untuk menjalankan fungsi dari dalam program yang berperilaku seperti dijelaskan di atas.

  • Harap berikan setidaknya tiga vektor uji untuk program atau pembungkus Anda (misalnya input dan output yang sesuai).

  • H dapat berupa desain novel Anda (lebih disukai) atau algoritma yang terkenal, selama Anda menerapkannya sendiri. Dilarang menggunakan fungsi hash bawaan apa pun, fungsi kompresi, sandi, PRNG, dll.

    Setiap built-in yang biasa digunakan untuk mengimplementasikan fungsi hashing (misalnya, konversi basis) adalah permainan yang wajar.

  • Output dari program atau fungsi Anda harus bersifat deterministik.

  • Seharusnya ada kompiler / juru bahasa gratis (seperti dalam bir) yang dapat dijalankan pada platform x86 atau x64 atau dari dalam browser web.

  • Program atau fungsi Anda harus cukup efisien dan harus mem-hash pesan apa pun di I di bawah 2 2 19 dalam waktu kurang dari satu detik.

    Untuk kasus tepi, waktu (dinding) yang diambil pada komputer saya (Intel Core i7-3770, 16 GiB RAM) akan menentukan.

  • Mengingat sifat tantangan ini, dilarang mengubah kode jawaban Anda dengan cara apa pun, apakah itu mengubah hasilnya atau tidak.

    Jika kiriman Anda telah dipecahkan (atau bahkan jika belum), Anda dapat memposting jawaban tambahan.

    Jika jawaban Anda tidak valid (mis. Tidak sesuai dengan spesifikasi I / O), harap hapus.

Contoh

Python 2.7, 22 byte

def H(M):
 return M%17

Pembungkus

print H(int(input()))

Perampok menantang

Tugas

Crack salah satu polisi kiriman dengan posting berikut di perampok benang : dua pesan M dan N di saya sehingga H (M) = H (N) dan M ≠ N .

Mencetak gol

  • Memecahkan setiap pengiriman polisi memberi Anda satu poin. Perampok dengan poin terbanyak menang.

    Dalam kasus dasi, perampok terikat yang memecahkan pengajuan menang paling lama.

Aturan tambahan

  • Setiap pengajuan polisi hanya dapat dibobol sekali.

  • Jika pengiriman polisi bergantung pada perilaku yang ditentukan atau tidak ditentukan implementasi, Anda hanya perlu menemukan celah yang berfungsi (dapat diverifikasi) pada mesin Anda.

  • Setiap celah milik jawaban terpisah di utas perampok.

  • Memposting upaya cracking yang tidak valid membuat Anda tidak bisa memecahkan submission tertentu selama 30 menit.

  • Anda tidak boleh merusak kiriman Anda sendiri.

Contoh

Python 2.7, 22 bytes oleh user8675309

1

dan

18

Papan peringkat

Pengajuan yang aman

  1. CJam, 21 bytes oleh eBusiness
  2. C ++, 148 bytes oleh tucuxi
  3. C ++, 233 (?) Byte oleh Vi.

Kiriman tidak terputus

Anda dapat menggunakan Cuplikan Stack ini untuk mendapatkan daftar jawaban yang belum retak.

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>


Jika fungsi hash keliru mengembalikan angka lebih besar dari 2 ^ 128-1, apakah itu membatalkan penyerahan, atau apakah kita akan mengambil hasilnya modulo 2 ^ 128?
Martin Ender

@ MartinBüttner: Ya, Anda harus mengambil modulo hasil 2 ^ 128.
Dennis

1
@Scimonster Tidak memenuhi persyaratan (hingga 2 ^ 30 bit input, 128 bit output)
CodesInChaos

1
Bukankah polisi dan perampok biasanya pergi sebaliknya?
haneefmubarak

2
Mungkin kita dapat memiliki aturan bahwa pengiriman harus menyertakan contoh hash, itu cukup menjengkelkan harus menjalankan submitter bahasa pemrograman yang dipilih untuk mendapatkan hasil untuk membandingkan implementasi cracking terhadap.
aaaaaaaaaaaa

Jawaban:


6

CJam, 21 byte

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

Mengambil string byte sebagai input.

Dalam pseudocode:

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

Contoh hash:

"" (string kosong) -> 1
"Uji" -> 2607833638733409808360080023081587841
"test" -> 363640467424586895504738713637444713

Mungkin sedikit di sisi sederhana, kisaran output hanya sedikit lebih dari 122 bit, penguatan iterasi tiga sudah agak rusak karena melakukan hal yang persis sama setiap waktu, jadi input yang hash ke 1 di pertama iterasi akan menjadi istirahat penuh. Tetapi ini singkat, dan tidak menyenangkan untuk menjadi terlalu aman.


Apakah ada versi C yang menyertainya seperti pada posting CJam lainnya?
Vi.

@ Vi. Tidak, setidaknya belum. Saya tidak pernah mencoba-coba bigint di C, apakah ada perpustakaan standar untuk itu?
aaaaaaaaaaaa

GMP ?
Vi.


1
@ Agawa001 Anda jadi bingung dengan terminologi Anda. Ini adalah algoritma hash fungsi triple-pass spons. Cipher Caesar adalah salah satu algoritma enkripsi khusus tanpa kondisi dalam.
aaaaaaaaaaaa

7

Python, 109 byte [ retak , dan lagi ]

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

Saya mencoba menerapkan fungsi Jenkins satu per satu waktu apa adanya, dengan satu-satunya perbedaan adalah benih dan jumlah bit.

Fakta menyenangkan: Rupanya Perl menggunakan hash Jenkins di beberapa titik .

Pembungkus

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

Contohnya

>>> 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 byte

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 adalah ekstensi GCC, dan berfungsi seperti yang diharapkan. Hash didasarkan pada iterasi FNV hash (saya telah meminjam prime mereka, meskipun amerupakan digit pertama dari Pi dalam hex) dengan rotasi seperti sha1 pada awal setiap iterasi. Mengkompilasi dengan -O3, hashing file 10MB membutuhkan waktu kurang dari 2 detik, jadi masih ada margin untuk meningkatkan iterasi di loop dalam - tapi saya merasa murah hati hari ini.

De-uglified (mengubah nama variabel, menambahkan komentar, spasi putih dan sepasang kawat gigi) untuk kesenangan Anda:

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
}

Saran golf dipersilahkan (bahkan jika saya tidak bisa memperbaiki kode berdasarkan pada mereka).

sunting: memperbaiki kesalahan ketik dalam kode yang tidak ditandai (versi golf tetap tidak berubah).


otampaknya tidak diinisialisasi. Di mana outputdinyatakan? Atau mungkin oadalah output?
Vi.

Sama untuk n. Sudahkah Anda benar-benar memeriksa kode "de-uglified" untuk dijalankan?
Vi.

Mulai bruteforcer ...
Vi.

Bahkan versi 3-putaran tidak mudah.
Vi.

@ Vi. Memperbaiki versi de-uglified - maaf karena tidak memeriksanya dengan lebih baik. Saya bangga dengan lingkaran dalam itu; U i=81;i-=3bisa lebih keji, tanpa biaya runtime yang signifikan.
tucuxi

5

CJam, 44 byte [ retak ]

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

Input ada di basis 10.

CJam lambat. Saya harap ini berjalan dalam 1 detik di beberapa komputer ...

Penjelasan

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.

Nah, dua hal dimensi tampaknya menjadi kelemahan ... Itu dimaksudkan untuk membuat beberapa perhitungan lambat lebih cepat di awal. Tapi itu tidak bisa berjalan dalam hitungan detik apa pun yang saya lakukan, jadi saya akhirnya menghapus kode yang lambat.

Seharusnya juga lebih baik jika saya telah menggunakan bit biner dan basis yang lebih tinggi.

Versi 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);
}

Bisakah Anda menambahkan deskripsi? Tidak semua orang tahu CJam.
orlp

@orlp Diedit ...
jimmy23013

Ini membutuhkan 0,4 detik pada komputer saya, jadi itu masih dalam kisaran yang diizinkan.
Dennis

Apa itu A, B, C, dan sebagainya? Beberapa matriks? Dimensi yang mana? Apakah bisa dengan mudah diimplementasikan dalam C?
Vi.

1
Retak , saya percaya.
Sp3000

5

C ++, 182 karakter (+ sekitar 51 karakter boilerplate)

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;}

Pelat boiler:

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
}

Program runnable dengan fungsi golf

#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
Saya pikir fungsi deklarasi dll diperhitungkan terhadap jumlah karakter.
Ypnypn

@Ypnypn, karakter yang dihitung dalam deklarasi fungsi golf turun.
Vi.

Apa hash output? Saya berasumsi itu ((h << 64) | j).
tucuxi

Iya nih. Atau hanya sepasang nomor 64-bit. Saya baru tahu __uint128_tsetelah menerapkan ini.
Vi.

1
@Dennis, Selesai .󠀠
Vi.

4

Pyth, 8 Retak

sv_`.lhQ

Cobalah online

Sedikit jawaban konyol, saya akan menjelaskan cara kerjanya karena kebanyakan orang tidak dapat membaca Pyth. Ini mengambil log natural dari satu ditambah input, dan kemudian mengubahnya menjadi string. String itu dibalik, kemudian dievaluasi dan kemudian dikonversi ke integer.

Terjemahan python akan terlihat seperti:

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


4

Python 3, 216 byte [ retak ]

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

Karena ketidakcocokan dengan spesifikasi saya bisa memikirkan setidaknya satu kerentanan sedikit , tetapi selain itu saya pikir ini setidaknya bukti kuat. Saya sudah memeriksa 10 juta hash pertama, antara lain.

Dalam hal golf, ini akan lebih pendek di Python 2, tapi saya sudah mengorbankan beberapa byte untuk efisiensi (karena mungkin tidak akan menang lagi).

Sunting: Ini adalah upaya saya untuk mengimplementasikan Very Smooth Hash , tapi sayangnya 128-bit terlalu kecil.

Pembungkus

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

Contohnya

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

Penjelasan kode

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

Contoh padding untuk 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 byte [ retak ]

Ini adalah program lengkap; tidak diperlukan pembungkus. Menerima input biner melalui stdin, dan menampilkan hash heksadesimal ke stdout.

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

Ini hanya menghitung hash 64-bit, jadi saya akan bertaruh di sini.

Jika ada yang bertanya-tanya, dua konstanta 'foo+'dan 'bar/'adalah bilangan prima 1718578987 dan 1650553391.


Contoh:

Abaikan nol terkemuka:

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

Input byte tunggal:

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

Input multi-byte:

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

Bagaimana perilakunya dengan 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Ismael Miguel

1
foo|(d5c9bef71d4f5d1b) dan foo\(d5c9bef71d4f5d1b) menghasilkan hash yang SANGAT mirip.
Ismael Miguel

1
Pecah !!! \x00dan \x00\x00!
Ismael Miguel

1
Berdasarkan komentar obrolan, saya yakin ini masih belum retak? Hanya mengecek ulang, karena komentar yang dibalik mungkin membingungkan bagi mereka yang membaca hash yang tidak terpecahkan.
Sp3000


3

J - 39 byte - retak

Berfungsi mengambil string sebagai input dan mengembalikan integer <2 128 . Saya berasumsi kita harus menamai fungsi kita agar valid, jadi hilangkan 3 karakter lagi dari hitungan jika kita bisa mengirimkan fungsi anonim.

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

Bagi Anda yang tidak membaca hieroglif, berikut adalah ringkasan dari apa yang saya lakukan.

  • a=.(2^128x)&|@^/@Ini adalah subrutin * yang mengambil array angka, dan kemudian memperlakukannya sebagai menara listrik, di mana eksponensial diambil mod 2 128 . Dengan "menara listrik", maksud saya jika Anda memberikan input 3 4 5 6, itu akan menghitung 3 ^ (4 ^ (5 ^ 6)).
  • (".p:@+5,9:)aFungsi ini mengambil string, mengubahnya menjadi angka N , dan kemudian menghitung bilangan prima ( n +5) -th dan ( n +9) -th, dan kemudian melempar adari sebelumnya. Yaitu, kita menemukan p(n+5) ^ p(n+9)mod 2 128 di mana p(k)adalah kprime -th.
  • H=:_8...\(a...)]Lakukan fungsi di atas pada sub-blok 8-karakter dari input, dan kemudian asemua hasil bersama-sama dan panggil fungsi hash yang dihasilkan H. Saya menggunakan 8 karakter karena kfungsi " -th prime" J gagal ketika p(k)> 31 , yaitu k=105097564aman terbesar k.

Memiliki beberapa output sampel. Anda dapat mencobanya sendiri secara online di tryj.tk , tetapi saya sangat merekomendasikan melakukan ini di rumah dengan mengunduh juru bahasa dari 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

* Secara teknis, ini bukan fungsi di dalam dan dari dirinya sendiri, itu melampirkan ke fungsi lain dan bertindak pada output mereka. Tapi ini adalah masalah semantik J, bukan perbedaan konseptual: aliran program seperti yang saya jelaskan di atas.



2

Python 3, 118 byte [ retak ]

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

Lekukan adalah satu tab. Hash sederhana, belum benar-benar diuji secara menyeluruh.

Panggil sebagai berikut:

print(H("123456789"))

hasil: 73117705077050518159191803746489514685


Bagaimana seharusnya integer input dikonversi menjadi string untuk digunakan dalam algoritma Anda?
feersum

@feersum base-10 string adalah apa yang saya uji. Itu tidak menggunakan apa pun kecuali ord(c), jadi benar-benar, string apa pun akan melakukan :) (kecuali hal-hal seperti nul chars, saya pikir itu membuat tabrakan hash sangat mudah. ​​Jadi tetap dengan string 0-9.)
tomsmeding

1
Pecah itu: codegolf.stackexchange.com/a/51160/41288 . Dimulai dengan mengamati bahwa string seperti "10000" dan "20000" menghasilkan hash yang sangat dekat. Mulai bermain-main dengan semakin banyak nol, dan setelah 128 atau lebih, setiap digit + k * 4 nol yang diulang mengembalikan hash yang sama terlepas dari k.
tucuxi

@tucuxi Sudah mengira seharusnya tidak terlalu keras; senang itu bukan hal sepele tetapi seseorang yang memecahkannya. Kerja bagus.
tommeding

2

C ++, 239 byte

Golf kode pertama saya! [ Mohon lembut ]

#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);}

Versi tidak disatukan:

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;
}

Bukan hash terbaik, dan jelas bukan kode terpendek yang ada. Menerima tips bermain golf dan berharap untuk meningkat!

Pembungkus

Mungkin bukan yang terbaik di dunia, tapi bungkusnya

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
Terlihat kokoh, tetapi dengan 64 bit, itu mungkin mengalami kekerasan. Ada sekitar 50% peluang untuk menemukan tabrakan dalam ~ sqrt (n) tes (dari antara n total output); 2 ^ 32 mencoba tidak sebanyak itu untuk pc modern.
tucuxi

Wrapper tidak memiliki inklusi tajuk dan secara umum mengarah ke banyak hash yang sama.
Vi.

Berikan beberapa sampel hash. Bagi saya baik "3" dan "33" mengarah ke 481c27f26cba06cf (menggunakan pembungkus ini).
Vi.

Retak: codegolf.stackexchange.com/a/51215/41288 . Saya menduga tepat sebelum @Vi. menemukan mengapa begitu banyak hash sama.
tucuxi

1
Tabrakan yang tepat (tanpa menggunakan bug): printf '33333333\x40\xF3\x32\xD6\x56\x91\xCA\x66' | ./hash7_-> a4baea17243177fd; printf '33333333\x77\x39\xF3\x82\x93\xDE\xA7\x2F' | ./hash7_-> a4baea17243177fd. Bruteforcer menemukan tabrakan di sini jauh lebih cepat dibandingkan dengan hash 64-bit lainnya di sini.
Vi.

2

Java, 299 291 282 byte, retak.

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)));}}

Apakah beberapa operasi di BigIntegers, kemudian mengambil modulo 2 128 hasil .


Bagaimana saya menjalankan ini? Ideone menolak untuk mengkompilasinya.
Martin Ender

1
Anda dapat menjalankannya di Ideone dengan mengganti nama kelas menjadi "Utama" atau menghapus kata kunci "publik" pertama (tetapi BUKAN yang kedua). Salah satu akan bekerja.
SuperJedi224


1
@ SuperJedi224 Mengapa tidak menghapus publicsendiri dulu , menyimpan 7 karakter?
user253751

@ imibis Karena itu saya tidak berpikir itu akan berfungsi dengan baik di Eclipse. Saya akan mencobanya. EDIT: Saya kira begitu. Itu mengejutkan.
SuperJedi224

2

C, 128 byte [ retak ]

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);}

Algoritma ini kurang lebih sama dengan upaya terakhir saya (di-crack oleh Vi.) , Tetapi sekarang memiliki roda hamster yang cukup untuk menghasilkan hash 128-bit yang tepat.

Empat konstanta utama dalam kode adalah sebagai berikut:

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

Seperti sebelumnya, ini adalah program lengkap tanpa perlu pembungkus. Integer I adalah input via stdin sebagai data biner mentah (big-endian), dan hash O dicetak dalam hex to stdout. Memimpin nol di I diabaikan.

Contoh:

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


Bukankah contoh Anda menunjukkan tabrakan di sana (dua yang pertama)?
mbomb007

@ mbomb007 Tidak. Masukan adalah angka antara 0 dan 2 ^ (2 ^ 30). 0x00 dan 0x0000 sama dengan nol, sehingga menghasilkan output yang sama.
squeamish ossifrage

2

C, 122 byte [ retak ]

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);}

Loop bersarang, LCG setengah-setengah, dan swapping variabel. Apa yang tidak untuk dicintai?

Berikut ini adalah versi yang tidak disenangi untuk dimainkan:

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;
}

Ini adalah program mandiri yang membaca dari STDIN dan mencetak ke STDOUT.

Contoh:

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

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

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

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

Dalam beberapa tolok ukur sederhana, hash sekitar 3MB / s data teks. Kecepatan hash tergantung pada input data itu sendiri, sehingga mungkin harus dipertimbangkan.



1

PHP 4.1, 66 byte [ retak ]

Saya hanya pemanasan.

Saya harap Anda menemukan insteresting ini.

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

Saya sudah mencobanya dengan angka sebesar 999999999999999999999999999.
Outputnya sepertinya berada dalam kisaran 2 128 .


PHP 4.1 diperlukan karena register_globals arahan.

Ini bekerja dengan secara otomatis membuat variabel lokal dari sesi, POST, DAPATKAN, PERMINTAAN dan cookie.

Itu menggunakan kunci a. (EG: akses selesaihttp://localhost/file.php?a=<number> ).

Jika Anda ingin mengujinya dengan PHP 4.2 dan yang lebih baru, coba ini:

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

Versi ini hanya berfungsi dengan POST dan GET.


Contoh output:

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

(Saya yakinkan Anda bahwa ada angka yang menghasilkan hash yang sama).



1

C, 134 byte, Retak

Ini adalah program C yang lengkap.

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);}

Kegunaannya: Idenya adalah untuk mengambil input sebagai array byte dan menambahkan byte pseudo acak (tetapi deterministik) pada akhirnya untuk membuat panjangnya sama dengan sekitar 2 2 30 (sedikit lebih). Implementasinya membaca input byte demi byte dan mulai menggunakan data acak semu ketika menemukan karakter pertama yang bukan digit.

Karena PRNG bawaan tidak diizinkan, saya menerapkannya sendiri.

Ada perilaku tidak terdefinisi / implementasi didefinisikan yang membuat kode lebih pendek (nilai akhir harus tidak ditandatangani, dan saya harus menggunakan berbagai jenis untuk nilai yang berbeda). Dan saya tidak bisa menggunakan nilai 128 bit dalam C. Versi yang kurang jelas:

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 bytes [[ Retak ]]

Ini sangat mirip dengan semua hash lainnya (LOOP, XOR, SHIFT, ADD) di sini. Ayo ambil perampok poin Anda;) Saya akan membuat yang lebih sulit setelah ini diselesaikan.

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

Wrapper (mengharapkan satu argumen dalam basis-16 yang juga dikenal sebagai heksadesimal):

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


1
Juga, saya tidak yakin entri ini memenuhi spesifikasi OP, karena pada mesin saya fungsinya membutuhkan beberapa detik pada input besar. Misalnya, H(2**(2**10))butuh sekitar 8 atau 9 detik, sementara H(2**(2**12))butuh sekitar 29 detik dan H(2**(2**14))lebih dari dua menit.
mathmandan

Anda benar sekali, saya seharusnya menguji waktu untuk input yang lebih besar. Selain itu, saya tampaknya lupa menjalankan tes saya sendiri setelah perubahan itu ditambahkan. Versi asli adalah tanpa shift (sebelum memposting) dan itu melewati "tidak ada tabrakan di 100000 integer" tes pertama saya: /
Bingung

1

Python 2.7 - 161 byte [[ Cracked ]]

Yah karena saya berhasil mengubah fungsi hash pertama saya menjadi versi yang tidak berguna sebelum mempostingnya, saya pikir saya akan memposting versi lain dari struktur yang sama. Kali ini saya mengujinya terhadap tabrakan sepele dan saya menguji sebagian besar kemungkinan input untuk kecepatan.

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

Wrapper (tidak dihitung dalam bytecount)

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

Jalankan contoh (input selalu berupa angka heksadesimal):

$ 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


Bagus sekali, jimmy :)
Bingung

1

Ruby, 90 Bytes

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

Algoritma hash yang sangat acak saya buat tanpa melihat hash nyata ... tidak tahu apakah itu baik. dibutuhkan string sebagai input.

Pembungkus:

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

Bisakah Anda memberikan bungkusnya pertanyaan yang dibutuhkan?
Dennis

Apa format inputnya? Saya mencoba dengan nomor tetapi katanya comparison of String with 255 failed (ArgumentError).
jimmy23013

H mengambil string, Membangun string mengambil nomor yang diperlukan oleh OP dan mengubahnya menjadi string.
MegaTom

Saya pikir Anda perlu gets.to_idi bungkusnya.
jimmy23013



0

PHP, 79 Bytes (retak. Dengan komentar):

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

Ini banyak hal-hal yang menakutkan melalui konversi tipe di php, yang membuatnya sulit untuk diprediksi;) (atau setidaknya saya harap begitu). Namun, itu bukan jawaban terpendek atau paling tidak terbaca.

Untuk menjalankannya, Anda dapat menggunakan PHP4 dan mendaftar global (dengan? I = 123) atau menggunakan baris perintah:

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

5
Nilai output hash terlihat floating-point. Dan itu sama untuk 300000000000000000000000000000000000000000000001 dan 300000000000000000000000000000000000000000000000000000.
Vi.

0

C # - 393 bytes retak

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"));}}

Tidak Disatukan:

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"));
    }
}

Saya belum pernah menyentuh kriptografi atau hashing dalam hidup saya, jadi lembutlah :)

Ini adalah implementasi sederhana hash FNV-1a dengan beberapa array berputar pada input. Saya yakin ada cara yang lebih baik untuk melakukan ini tetapi ini adalah yang terbaik yang bisa saya lakukan.

Mungkin menggunakan sedikit memori pada input panjang.


Cracked: codegolf.stackexchange.com/a/51277/101 Selain memiliki bantalan yang salah, ini bukan hash kriptografi, ada begitu banyak cara untuk memecahkannya.
aaaaaaaaaaaa

0

Python 2, 115 byte [ Sudah retak! ]

Oke, ini usaha terakhir saya. Hanya 115 byte karena baris baru final tidak diperlukan.

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

Ini adalah program lengkap yang memasukkan bilangan bulat desimal pada stdin dan mencetak nilai hash desimal pada stdout. Nol memimpin ekstra akan menghasilkan nilai hash yang berbeda, jadi saya hanya akan berasumsi bahwa input tidak memilikinya.

Ini bekerja dengan memasukkan 197-digit potongan nomor input melalui eksponensial modular. Tidak seperti beberapa bahasa, int()fungsi selalu default ke basis 10, jadiint('077') juga 77, bukan 63.

Output sampel:

$ 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
Itu tidak menggunakan urutan blok ... Retak .
jimmy23013

Ugh. Saya menyerah :-(
squeamish ossifrage
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.