Kriptografik karma golf


34

Bu yarışma bitti.

mücadelenin doğası gereği , ilgili soyguncularla mücadeleye olan ilgi azaldığında, polisler mücadelesi çok daha kolay hale gelir. Bu nedenle, yine de karma işlevler yayınlayabildiğiniz halde, cevabınız kabul edilmeyecek veya büyük afişin bir parçasını oluşturamayacak.

Bu zorluk kısa uygulanması için bir arayıştır hash fonksiyonu olan çarpışma dirençli , yani, aynı karma ile iki farklı iletileri bulmak için olanaksız olmalıdır.

Bir polis olarak, kod boyutu ile çarpışma direnci arasında en iyi dengeyi bulmak için bir karma işlevi icat etmeye ve uygulamaya çalışın. Çok fazla bayt kullanın ve başka bir polis sizi aşacak!

Bir soyguncusu olarak, polislerin girişimlerini engelleyerek işlevlerini kırıp, uygun olmadıklarını kanıtlamaya çalışıyorsunuz. Bu, algoritmalarını güçlendirmek için daha fazla byte kullanmaya zorlar!

Polisler mücadelesi

Görev

Bir kriptografik hash fonksiyonu uygulamak H: I -> Ç seçtiğiniz ait ben 2 altındaki tüm negatif olmayan tamsayılar kümesidir 2 30 ve O 2 altındaki tüm negatif olmayan tamsayılar kümesidir 128 .

Ya uygulayabilir H kabul eder ve tek bir tamsayı, bir tamsayı dize gösterimini ya da tamsayı dizisi ya da 10 tabanına ya da 16 STDOUT STDIN'den ve baskılar okur tam bir program döndüren bir gerçek fonksiyonu olarak göstermektedir.

puanlama

  • H aşağıda tanımlanan soyguncularla mücadeleye karşı koymak zorunda .

    Bir soyguncu gönderinizi gönderdikten sonraki ilk 168 saat içinde yenerse, kırıldığı kabul edilir .

  • H'nin uygulanması mümkün olduğu kadar kısa olmalıdır. İzlenmemiş en kısa sürede yapılan başvurular polis yarışmasının galibi olacaktır.

Ek kurallar

  • H'yi bir işlev olarak uygularsanız , lütfen işlevi yukarıda açıklandığı gibi davranan bir programın içinden yürütmek için bir sarmalayıcı sağlayın.

  • Lütfen programınız veya paketleyiciniz için en az üç test vektörü sağlayın (örnek girdiler ve bunlara karşılık gelen çıktılar).

  • H , kendiniz uyguladığınız sürece, yeni tasarımınız (tercih edilen) veya iyi bilinen bir algoritma olabilir. Her türlü yerleşik karma işlevi, sıkıştırma işlevi, şifre, PRNG vb. Kullanmak yasaktır.

    Karma işlevlerini (örneğin temel dönüştürme) uygulamak için yaygın olarak kullanılan herhangi bir yerleşik oyun adildir.

  • Programınızın veya fonksiyonunuzun çıktısı deterministik olmalıdır.

  • Bir x86 veya x64 platformunda veya bir web tarayıcısından çalıştırılabilen (biradaki gibi) ücretsiz bir derleyici / tercüman bulunmalıdır.

  • Programınız veya işlevin makul derecede verimli olmalı ve I 2 2 19'ın altındaki herhangi bir iletiyi bir saniyeden daha kısa sürede almalıdır .

    Son durumlarda, makinemde (duvarda) geçen süre (Intel Core i7-3770, 16 GiB RAM) belirleyici olacak.

  • Bu zorluğun niteliği göz önüne alındığında, cevabınızın kodunu çıktısını değiştirip değiştirmemesine herhangi bir şekilde değiştirmeniz yasaktır.

    Gönderiminiz kırılmışsa (veya olmasa bile), ek bir cevap gönderebilirsiniz.

    Cevabınız geçersizse (örneğin, G / Ç spesifikasyonuna uymuyorsa), lütfen silin.

Örnek

Python 2.7, 22 bayt

def H(M):
 return M%17

sarıcı

print H(int(input()))

Soyguncular mücadele

Görev

De aşağıdaki yayınlayarak başvuru polisin herhangi çatlak iplik haydutlarin iki mesaj: M ve K olarak bir şekilde , H (M) = H (H) ve M ≠ N .

puanlama

  • Her polis gönderisini kırmak sana bir puan kazandırır. En çok puan alan hırsız kazanır.

    Beraberlik durumunda, en uzun gönderimi kıran bağlı soyguncu kazanır.

Ek kurallar

  • Her polis başvurusu sadece bir kez kırılabilir.

  • Bir polis teslimi, uygulama tarafından tanımlanmış veya tanımlanmamış davranışa dayanıyorsa, yalnızca makinenizde (doğrulanabilir şekilde) çalışan bir çatlak bulmanız gerekir.

  • Her çatlak, soyguncuların ipindeki ayrı bir cevaba aittir.

  • Geçersiz bir çatlama girişimi göndermek, söz konusu gönderimi 30 dakika boyunca kırmanızı engeller.

  • Kendi gönderinizi kıramazsınız.

Örnek

Python 2.7, 22 byte kullanıcı8675309 tarafından

1

ve

18

Liderler Sıralaması

Güvenli gönderimler

  1. CJam, eBusiness tarafından 21 bayt
  2. C ++, 148 byte tucuxi tarafından
  3. C ++, 233 (?) Bytes Vi.

Uncracked gönderimler

Henüz kesilmemiş cevapların bir listesini almak için bu Yığın Parçacığını kullanabilirsiniz.

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>


Bir karma işlevi hatalı bir şekilde 2 ^ 128-1'den büyük sayıları döndürürse, bu gönderim geçersiz olur mu, yoksa sadece modulo 2 ^ 128 sonucunu mu alırız?
Martin Ender

@ MartinBüttner: Evet, modulo 2 ^ 128 sonucunu almak zorundasınız.
Dennis,

1
@Scimonster Gereksinimleri karşılamıyor (en fazla 2 ^ 30 bit girdi, 128 bit çıktı)
CodesInChaos 31:15

1
Polisler ve soyguncular genellikle öbür tarafa gitmez mi?
haneefmubarak

2
Belki de gönderilerin örnek karmaları içermesi gerektiğine dair bir kurala sahip olabiliriz;
aaaaaaaaaaaa

Yanıtlar:


6

CJam, 21 bayt

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

Girdi olarak bir bayt dizisi alır.

Sözde kodda:

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

Örnek karmalar:

"" (boş dize) -> 1
"Test" -> 2607833638733409808360080023081587841
"test" -> 363640467424586895504738713637444713

Basit tarafta biraz olabilir, çıkış aralığı sadece 122 bitten biraz fazla, üçlü yineleme güçlendirmesi zaten her seferinde tamamen aynı şeyi yaptığından biraz kırıldı, bu yüzden ilk girişte 1 olacak yineleme tam bir mola olacak. Ancak bu kısa ve güvenli olmanın hiç eğlencesi yok.


Diğer CJam postunda olduğu gibi eşlik eden bir C versiyonu var mı?
Vi.

@Vi. Hayır, en azından henüz değil. C’de bigint ile hiç uğraşmadım, bunun için standart bir kütüphane var mı?
aaaaaaaaaaaa

GMP ?
Vi.


1
@ Agawa001 Terminolojinizi karıştırıyorsunuz. Üç geçişli bir sünger işlevi karma algoritmasıdır. Sezar şifresi, içsel durumu olmayan belirli bir şifreleme algoritmasıdır.
aaaaaaaaaaaa

7

Python, 109 byte [ çatlamış , ve tekrar ]

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'in her seferinde bir işlevini olduğu gibi gerçekleştirmeye çalıştım , tek fark tohum ve bit sayısıydı.

Eğlenceli gerçek: Görünüşe göre Perl, Jenkins'in hash değerini bir noktada kullandı .

sarıcı

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

Örnekler

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

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 bir GCC uzantısıdır ve beklendiği gibi çalışır. Karma, her yinelemenin başlangıcında sha1 benzeri bir dönüşle FNV karma değerinin yinelemesine dayanır (temel değerlerini aHex cinsinden ilk Pi rakamları olmasına rağmen ödünç aldım ) . Derlemek , 10 MB'lık bir dosyaya sahip olmak 2 saniyenin altında bir zaman alır, bu yüzden iç döngüdeki yinelemelerin artması için hala bir marj var - ama bugün kendimi cömert hissediyorum.-O3

Çatlama zevki için, kaldırıldı (değişken isimler değiştirildi, yorumlar eklendi, boşluklar ve bir çift parantez):

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
}

Golf önerileri memnuniyetle karşılanmaktadır (bunlara dayanarak kodu geliştiremesem bile).

düzenleme: kodu kaldırıldı kodunda sabit yazım hataları (golf sürüm değişmeden kalır).


obaşlatılmamış gibi görünüyor. Nerede outputilan edilir? Ya da belki obir output?
Vi.

Aynı şey için n. Çalıştırmak için "devre dışı bırakılmış" kodu kontrol ettiniz mi?
Vi.

Bruteforcer'ı başlattım ...
Vi.

3 tur versiyonu bile kolay değil.
Vi.

@Vi. Sabit sürümde kaldırılmış sürüm - daha iyi kontrol etmediğim için üzgünüm. Bu iç döngü ile gurur duyuyorum; U i=81;i-=3önemli çalışma zamanı maliyetleri olmadan daha aşağılık olabilirdi.
tucuxi

5

CJam, 44 bayt [ kırık ]

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

Giriş 10’da.

CJam yavaş. Umarım bazı bilgisayarlarda 1 saniye içinde çalışır ...

açıklamalar

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.

Eh, iki boyutlu şeyler zayıf görünüyordu ... Başlangıçta bazı yavaş hesaplamalar daha hızlı yapmak için tasarlanmıştı. Ama ne yaparsam yapayım ikinci saniyede çalıştırılamaz, bu yüzden yavaş kodu nihayet kaldırdım.

İkili bitler ve daha yüksek bazlar kullandıysam daha iyi olmalı.

C sürümü

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

Lütfen bir açıklama ekler misiniz? Herkes CJam'ı tanımıyor.
orlp

@orlp Düzenlendi ...
jimmy23013

Bilgisayarımda bu 0,4 sn sürüyor, izin verilen aralıkta iyi.
Dennis,

A, B, C ve benzeri nedir? Bazı matrisler? Hangi boyutlar? C de kolayca uygulanabilir mi?
Vi.

1
Çatlak , inanıyorum.
Sp3000

5

C ++, 182 karakter (+ yaklaşık 51 karakter kazan)

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

Ortak metin:

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
}

Golf fonksiyonu ile çalıştırılabilir program

#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
İşlev bildirimi vb. Karakter sayımına göre sayılır.
Ypnypn

@Ypnypn, aşağıya atılan bir işlev bildiriminde bulunan karakterleri saydı.
Vi.

Çıktı karma nedir? Varsayıyorum ((h << 64) | j).
tucuxi

Evet. Ya da sadece bir çift 64 bit sayılar. Sadece bunu __uint128_tuyguladıktan sonra öğrendim .
Vi.

1
@Dennis, Tamamlandı.
Vi.

4

Pyth, 8 Kırık

sv_`.lhQ

Çevrimiçi deneyin

Aptalca bir cevap biraz, nasıl çalıştığını açıklayacağım çünkü çoğu insan Pyth'i okuyamıyor. Bu, bir girişin doğal günlüğünü ve girişini alır ve sonra bunu bir dizeye dönüştürür. Bu dize ters çevrilir ve sonra değerlendirilir ve sonra bir tam sayıya dönüştürülür.

Bir python çevirisi şöyle görünür:

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


4

Python 3, 216 bayt [ kırık ]

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

Teknik özellikteki bir uyumsuzluk nedeniyle, en az bir küçük güvenlik açığı olduğunu düşünebilirim, ancak bunun en azından kaba kuvvet kanıtı olduğunu düşünüyorum. Diğer şeylerin yanı sıra ilk 10 milyon hastayı kontrol ettim.

Golf açısından bu Python 2'de daha kısa olacaktır, ancak verimlilik için bazı baytları feda ettim (muhtemelen yine de kazanamayacağından).

Düzenleme: Bu benim çok düzgün hash uygulamama girişimdi , fakat ne yazık ki 128 bit çok küçüktü.

sarıcı

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

Örnekler

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

Kod açıklaması

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

Dolgu örneği 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 bayt [ kırık ]

Bu tam bir programdır; sarıcı gerekmez. Stdin üzerinden ikili girişi kabul eder ve onaltılık bir karma değerini stdout'a verir.

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

Bu sadece 64 bitlik bir hash hesaplar, bu yüzden burada biraz kumar alıyorum.

Kimsenin merak etmesi durumunda, iki sabit 'foo+'ve 'bar/'1718578987 ve 1650553391 numaralı asıl sayılardır.


Örnekler:

Baştaki sıfırları yok sayar:

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

Tek bayt girişler:

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

Çok baytlı girişler:

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

Nasıl olur?
Ismael Miguel,

1
foo|(d5c9bef71d4f5d1b) ve foo\(d5c9bef71d4f5d1b), ÇOK benzer karma değerler üretir .
Ismael Miguel,

1
Kırdı !!! \x00ve \x00\x00!
Ismael Miguel,

1
Sohbet yorumlarına göre, bunun hala henüz kırılmadığına inanıyorum? Sadece iki kez kontrol edin, çünkü yorum yapılan yorum, kırılmamış kargaşayı gözden geçirenlerin kafasını karıştırabilir.
Sp3000


3

J - 39 bayt - kırık

Girdi olarak bir dize alarak ve <2 128 tamsayısını döndüren işlev . İşlevimizi geçerli kılmak için ad vermemiz gerektiğine inanıyorum, bu nedenle adsız işlevler gönderebilirsek sayımdan 3 karakter daha atarız.

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

Hiyeroglif okumayanlarınız için, işte yaptığım işin özeti.

  • a=.(2^128x)&|@^/@Bu, bir sayı dizisi alan bir alt yordamdır * ve üstele üstelif mod 2 128'in alındığı bir güç kulesi gibi davranır . "Güç kulesi" ile, eğer girişi girdiyseniz 3 4 5 6hesaplardı 3 ^ (4 ^ (5 ^ 6)).
  • (".p:@+5,9:)aBu işlev bir dize alır, onu N sayısına dönüştürür ve ( n +5) -th ve ( n +9) -th asal sayılarını hesaplar ve sonra ada ondan önce atar . Başka bir deyişle, p(n+5) ^ p(n+9)mod 2 128'in birinci üssü nerede p(k)olduğunu görüyoruz k.
  • H=:_8...\(a...)]Yukarıdaki işlevi, girişin 8 karakterli alt bloklarında gerçekleştirin ve ardından atüm sonuçları bir araya getirin ve elde edilen hash fonksiyonunu çağırın H. 8 karakter kullanıyorum, çünkü J'nin " k-th üssü" işlevi p(k)> 2 31 , yani k=105097564en büyük kasa olduğunda başarısız oluyor k.

Bazı örnek çıktıları al. Sen adresinden çevrimiçi olarak bu kendinizi deneyebilirsiniz tryj.tk , ama gerçekten dan tercüman indirerek evde bunu tavsiye 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

* Teknik olarak, kendi başına bir işlev değildir, diğer işlevlere eklenir ve bunların çıktısına etki eder. Ancak bu J'nin anlamsal bir sorunudur, kavramsal bir fark değildir: program akışı yukarıda açıkladığım şekildedir.



2

Python 3, 118 bayt [ kırık ]

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

Girinti tek bir sekmedir. Basit karma, henüz tam olarak test etmedim.

Aşağıdaki gibi arayın:

print(H("123456789"))

sonuç: 73117705077050518159191803746489514685


Giriş tamsayısı algoritmanızda kullanmak için bir dizgeye nasıl dönüştürülmeli?
feersum 19

@ feersum base-10 string test ettiğim şey. Hiçbir şey kullanmaz ama ord(c)gerçekte, herhangi bir dize yapacaktır :) (nul karakterleri hariç, sanırım bu karmaşanın çarpışmasını gerçekten kolaylaştırır. Öyleyse 0-9 dizeyle
yapış

1
Kırdı : codegolf.stackexchange.com/a/51160/41288 . "10000" ve "20000" gibi dizgilerin çok yakın hassalar ürettiğini gözlemleyerek başladı. Sıfır ve daha fazla sıfırla oynamaya başladı ve 128 ya da öylesine sonra, herhangi bir rakam + k * 4 sıfırlar tekrarlar, k değerinden bağımsız olarak aynı hash ile döner.
tucuxi

@tucuxi Zaten çok zor olmamalıydı sanıyordum ; bunun önemsiz olmadığını, ancak birinin yine de kırdığı için sevindim. İyi iş.
15’te

2

C ++, 239 bayt

Benim ilk kod golf! [ Lütfen nazik ol ]

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

Ungolfed versiyonu:

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

En iyi karma değil ve kesinlikle varolan en kısa kod değil. Golf ipuçlarını kabul etmek ve gelişmeyi ümit etmek!

sarıcı

Muhtemelen dünyanın en iyisi değil, yine de bir sarıcı.

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
Sağlam görünüyor, ancak 64 bit ile kaba zorlanmaya maruz kalabilir. Rt sqrt (n) testlerinde çarpışma bulma olasılığı yaklaşık% 50'dir (n toplam çıktılar arasından); 2 ^ 32 deneme, modern bir bilgisayar için o kadar da değil.
tucuxi

Sarıcı, başlık kapanmalarından yoksundur ve genel olarak birçok eşit karmaya yol açar.
Vi.

Bazı karma örnekler verin. Benim için hem "3" hem de "33" 481c27f26cba06cf (bu sargının kullanılması) ile sonuçlanır.
Vi.

Çatlak: codegolf.stackexchange.com/a/51215/41288 . @Vi'den hemen önce şüpheleniyorum. Neden bu kadar çok karma değerin eşit olduğunu buldum.
tucuxi

1
Doğru çarpışma (böcek kullanımı olmadan): 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, buradaki çarpma işlemlerini, diğer 64-bitlik karma değerlerine kıyasla çok daha hızlı buluyor.
Vi.

2

Java, 299 291 282 bayt, kırık.

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

BigIntegers üzerinde bazı işlemler yapar, ardından modulo 2 128 sonucunu alır .


Bunu nasıl çalıştırırım? Ideone derlemeyi reddediyor.
Martin Ender

1
Sınıfı "Ana" olarak değiştirerek veya ilk "genel" anahtar kelimeyi kaldırarak (ikincisini DEĞİL) İdeone üzerinde çalıştırabilirsiniz. Her ikisi de işe yarayacak.
SuperJedi224


1
@ SuperJedi224 Neden public7 karakterden tasarruf edersiniz ?
user253751

@ immibis Çünkü o zaman Eclipse'de işe yarayacağını sanmıyorum. Yine de deneyeceğim. EDIT: Sanırım öyle. Bu bir sürpriz.
SuperJedi224

2

C, 128 bayt [ kırık ]

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

Bu aşağı yukarı aynı algoritma gibidir benim son çaba azami (Vi tarafından kırılmıştır). , ama şimdi doğru 128 bit karmaları oluşturmak için yeterli bir hamster tekerleği var.

Koddaki dört ana sabit aşağıdaki gibidir:

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

Daha önce olduğu gibi, bu bir sarmalayıcıya ihtiyaç duymadan tam bir programdır. I tamsayısı stdin üzerinden ham ikili veri (big-endian) ve karma olarak girilir. O onaltılık olarak stdout'a basılır. I'in içindeki sıfırlar yoksayılır.

Örnekler:

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


Örneğiniz tam orada bir çarpışma göstermedi mi (ilk ikisi)?
mbomb007 19

@ mbomb007 Hayır. Giriş, 0 ile 2 ^ (2 ^ 30) arasında bir sayıdır. 0x00 ve 0x0000 ikisi de sıfıra eşittir, bu nedenle aynı çıktıyı üretirler.
squeamish ossifrage

2

C, 122 bayt [ kırık ]

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

İç içe döngüler, yarı katlı LCG'ler ve değişken takas. Ne aşk değil?

İşte oynayabileceğiniz bir ungolf'd versiyonu:

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

Bu, STDIN'den okuyan ve STDOUT'a basan tamamen kendi kendine bir programdır.

Örnek:

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

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

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

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

Bazı basit ölçütlerde, 3 MB / sn civarında metin verisine sahiptir. Karma hızı, giriş verilerinin kendisine bağlıdır, bu yüzden muhtemelen dikkate alınmalıdır.



1

PHP 4.1, 66 bayt [ kırık ]

Sadece ısınıyorum.

Umarım bu ilgi çekici bulursun.

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

9999999999999999999999999999999 sayılarını denedim
. Çıktı 2 128 aralığında görünüyordu .


Yönergeden dolayı PHP 4.1 gereklidir register_globals.

Oturum, POST, GET, REQUEST ve çerezlerden yerel değişkenleri otomatik olarak oluşturarak çalışır.

Anahtarını kullanır a. (EG: erişim bitti http://localhost/file.php?a=<number>).

PHP 4.2 ve daha yenisiyle test etmek istiyorsanız, şunu deneyin:

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

Bu sürüm sadece POST ve GET ile çalışır.


Örnek çıktı:

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

(Aynı karmaşayı üreten sayılar olduğunu temin ederim).



1

C, 134 bayt, Kırık

Bu tamamlanmış bir C programıdır.

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

Ne yapar: Fikir, byte dizisi olarak girdi almak ve uzunluğu yaklaşık 2 2 30'a eşit yapmak için sonunda rastgele (ancak deterministik) byte'lar eklemekdir. (biraz daha fazla) . Uygulama, byte ile byte okur ve rakam olmayan ilk karakteri bulduğunda sözde rasgele verileri kullanmaya başlar.

Yerleşik PRNG'ye izin verilmediğinden kendim uyguladım.

Kodu kısaltan tanımsız / uygulama tanımlı davranış var (son değerin imzasız olması gerekir ve farklı değerler için farklı türler kullanmalıyım). C de 128 bitlik değerleri kullanamadım. Daha az karışık sürüm:

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 bayt [[ Kırık ]]

Bu, diğer tüm (LOOP, XOR, SHIFT, ADD) karmaları ile oldukça benzer. Gelin puanlarınızı soyguncular olsun;) Bu çözüldükten sonra daha da zorlanacağım.

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

Sarmalayıcı (taban-16 da onaltılık olarak da bilinen bir argüman bekler):

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


1
Ayrıca, bu girişin OP'nin spesifikasyonlarına uygun olduğundan emin değilim, çünkü makinemde işlev büyük girişlerde birkaç saniye alıyor. Örneğin, H(2**(2**10))yaklaşık 8 veya 9 saniye H(2**(2**12))sürdü, yaklaşık 29 saniye H(2**(2**14))sürdü ve iki dakika sürdü.
mathmandan

Kesinlikle haklısın, açıkçası daha büyük girdiler için zamanlamayı test etmeliydim. Ayrıca, bu vardiya eklendikten sonra kendi testimi çalıştırmayı unuttum. Orijinal versiyon kayma olmadan (göndermeden önce) ve "ilk 100000 tam sayıda çarpışma yok" testini geçiyordu: /
Puzzled

1

Python 2.7 - 161 bayt [[ Kırık ]]

İlk karma işlevimi göndermeden önce işe yaramaz bir sürüme geçirmeyi başardığımdan, benzer bir yapının başka bir sürümünü göndereceğimi düşünüyorum. Bu sefer önemsiz çarpışmalara karşı test ettim ve olası giriş büyüklüklerinin çoğunu hız için test ettim.

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

Sarmalayıcı (bayt sayılmaz)

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

Örnek çalıştır (giriş her zaman onaltılık bir sayıdır):

$ 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


Aferin jimmy :)
Puzzled

1

Ruby, 90 Bayt

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

Herhangi bir gerçek karmaya bakmadan oluşturduğum oldukça rasgele bir karma algoritması ... iyi olup olmadığı hakkında hiçbir fikrim yok. girdi olarak bir dize alır.

sarıcı:

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

Lütfen sorunun gerektirdiği sargıyı verir misiniz?
Dennis,

Giriş formatı nedir? Bir numarayla denedim ama yazıyor comparison of String with 255 failed (ArgumentError).
jimmy23013

H bir string alır, Build string OP tarafından istenen sayıyı alır ve onu bir dizgeye dönüştürür.
MegaTom

Sanırım sarıcıya ihtiyacın var gets.to_i.
jimmy23013



0

PHP, 79 Bayt (kırık. Yorum yaz):

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

Bu, php'deki tip-dönüşümler yoluyla çok fazla korkutucu şey yapmaz; bu da tahmin etmeyi zorlaştırır;) (ya da en azından öyle umuyorum). Ancak, en kısa veya en okunamaz cevap değil.

Çalıştırmak için PHP4'ü kullanabilir ve globals'ı (? İ = 123 ile) kaydedebilir veya komut satırını kullanabilirsiniz:

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

5
Hash'in çıkış değeri kayan noktaya benziyor. Ve 300000000000000000000000000000000000000000000001 ve 300000000000000000000000000000000000000000000000’de aynıdır
Vi.

0

393 bayt kırık

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

Ungolfed:

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

Hayatımda şifreleme veya karmaşaya hiç dokunmadım, bu yüzden nazik ol :)

Girdide dönen bazı dizilerle FNV-1a karma işleminin basit bir uygulamasıdır . Bunu yapmanın daha iyi bir yolu olduğundan eminim ama yapabileceğimin en iyisi bu.

Uzun girişlerde biraz bellek kullanabilir.


Cracked: codegolf.stackexchange.com/a/51277/101 Hatalı dolgunun üstüne, bu kriptografik bir karma değil, kırmanın birçok yolu var.
aaaaaaaaaaaa

0

Python 2, 115 bayt [ Zaten Cracked! ]

Tamam, işte son çabam. Son satır gerekli olmadığından yalnızca 115 bayt.

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

Bu, stdin'e ondalık bir tamsayı giren ve stdout'a ondalık bir hash değeri basan eksiksiz bir programdır. Ekstra önde gelen sıfırlar farklı karma değerlere neden olur, bu nedenle girişin hiçbirine sahip olmadığını varsayacağım.

Bu, giriş numarasının 197 basamaklı parçalarını modüler bir üsteli doldurma yoluyla çalışır. Bazı dillerden farklı olarak, int()işlev her zaman varsayılan 10'dur, yaniint('077') 63'tür, 77'dir.

Örnek çıktılar:

$ 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
Blok sırasını kullanmadı ... Çatlak .
jimmy23013

Ugh.
Vereceğim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.