Lockers vs. Crackers: The Five-Element Sequence


31

La sfida

Una semplice sfida "spia contro spia".

Scrivi un programma con le seguenti specifiche:

  1. Il programma può essere scritto in qualsiasi lingua ma non deve superare i 512 caratteri (come rappresentato in un blocco di codice su questo sito).
  2. Il programma deve accettare 5 numeri interi a 32 bit con segno come input. Può assumere la forma di una funzione che accetta 5 argomenti, una funzione che accetta un singolo array di 5 elementi o un programma completo che legge 5 numeri interi da qualsiasi input standard.
  3. Il programma deve emettere un numero intero a 32 bit con segno.
  4. Il programma deve restituire 1 se e solo se i cinque ingressi, interpretati come una sequenza, corrispondono a una specifica sequenza aritmetica a scelta del programmatore, chiamata "chiave". La funzione deve restituire 0 per tutti gli altri ingressi.

Una sequenza aritmetica ha la proprietà che ogni elemento successivo della sequenza è uguale al suo predecessore più una costante fissa a.

Ad esempio, 25 30 35 40 45è una sequenza aritmetica poiché ogni elemento della sequenza è uguale al suo predecessore più 5. Allo stesso modo, 17 10 3 -4 -11è una sequenza aritmetica poiché ogni elemento è uguale al suo predecessore più -7.

Le sequenze 1 2 4 8 16e 3 9 15 6 12non sono sequenze aritmetiche.

Una chiave può essere qualsiasi sequenza aritmetica di tua scelta, con la sola limitazione che le sequenze che comportano un overflow di numeri interi non sono consentite. Cioè, la sequenza deve essere rigorosamente crescente, rigorosamente decrescente o avere tutti gli elementi uguali.

Ad esempio, supponiamo di scegliere la chiave 98021 93880 89739 85598 81457. Il programma deve restituire 1 se gli ingressi (in sequenza) corrispondono a questi cinque numeri e 0 in caso contrario.

Si noti che i mezzi per proteggere la chiave dovrebbero essere del proprio nuovo design. Inoltre, non sono consentite soluzioni probabilistiche che potrebbero restituire falsi positivi con qualsiasi probabilità diversa da zero. In particolare, non utilizzare hash crittografici standard, incluse le funzioni di libreria per hash crittografici standard.

Il punteggio

Il numero / i invii più brevi non crackati per numero di personaggi saranno dichiarati vincitori.

In caso di confusione, non esitare a chiedere o commentare.

La contro-sfida

Tutti i lettori, compresi quelli che hanno presentato i propri programmi, sono incoraggiati a "infrangere" i contributi. Un invio viene decifrato quando la sua chiave viene pubblicata nella sezione commenti associati. Se un invio persiste per 72 ore senza essere modificato o crackato, viene considerato "sicuro" e qualsiasi successivo successo nel cracking verrà ignorato per motivi di contest.

Vedi "Disclaimer" di seguito per i dettagli sulla politica aggiornata del punteggio di cracking.

Gli invii incrinati vengono eliminati dalla contesa (a condizione che non siano "sicuri"). Non dovrebbero essere modificati. Se un lettore desidera presentare un nuovo programma, deve farlo in una risposta separata.

I cracker con il punteggio più alto saranno dichiarati vincitori insieme agli sviluppatori dei programmi vincenti.

Si prega di non crackare la propria richiesta.

Buona fortuna. :)

Classifica

Penultima classifica (in attesa della sicurezza della presentazione di Dennis 'CJam 49).

Armadietti sicuri

  1. CJam 49, Dennis
  2. CJam 62, Dennis al sicuro
  3. CJam 91, Dennis al sicuro
  4. Python 156, Maarten Baert al sicuro
  5. Perl 256, sicuro Cile
  6. Java 468, Geobits sicuro

Crackers inarrestabili

  1. Peter Taylor [Ruby 130, Java 342, Mathematica 146 *, Mathematica 72 *, CJam 37]
  2. Dennis [Pyth 13, Python 86 *, Lua 105 *, GolfScript 116, C 239 *]
  3. Martin Büttner [Javascript 125, Python 128 *, Ruby 175 *, Ruby 249 *]
  4. Tyilo [C 459, Javascript 958 *]
  5. freddieknets [Mathematica 67 *]
  6. Ilmari Karonen [Python27 182 *]
  7. nitroso [C 212 *]

* invio non conforme

Dichiarazione di non responsabilità (aggiornata alle 23:15 EST, il 26 agosto)

Con i problemi di punteggio che finalmente raggiungono la massa critica (dato che due terzi degli invii crackati sono finora non conformi), ho classificato i migliori cracker in termini di numero di invii crackati (primario) e numero totale di personaggi in invii crackati conformi (secondario).

Come in precedenza, le richieste esatte sono state violate, la lunghezza delle comunicazioni e il loro stato conforme / non conforme sono tutti contrassegnati in modo che i lettori possano dedurre le proprie classifiche se ritengono che le nuove classifiche ufficiali siano inique.

Mi scuso per aver modificato le regole così tardi nel gioco.


6
Come verificherai che i programmi soddisfino il punto 4? Ti aspetti che le persone modifichino le risposte sicure per aggiungere una prova? Gli invii probabilistici sono consentiti sulla base dell'ipotesi che le funzioni hash siano ideali e che la possibilità di una collisione con un altro elemento dello spazio a 48 bit (secondo la stima sopra) sia trascurabile?
Peter Taylor,

2
Il sistema di punteggio sembra incoraggiare i cracker a ignorare i blocchi più corti perché ottengono un punteggio migliore rompendo due blocchi lunghi rispetto a due piccoli.
Peter Taylor,

3
@COTO Penso che il problema sia che puoi ottenere solo 2 punteggi di cracking e solo il più breve. Quindi perché non aspettare e sperare e più si presenta? Ad esempio, Martin ora non ha alcun incentivo a decifrare il mio lucchetto (più lungo), dato che ne ha già craccati due più corti. Chiunque spacca il mio ora lo batterà senza nemmeno doverne fare un secondo.
Geobits il

1
Penso che un sistema di punteggio migliore potrebbe essere la somma dei tempi totali tra domanda e crack. In questo modo, rompere un mucchio di quelli facili può essere battuto, e la vera ricompensa viene dal rompere quelli veramente difficili.
isaacg,

1
Sono nuovo nel golf, quindi forse è una domanda stupida, mi dispiace per quello. Perché la lunghezza del codice è misurata in caratteri e non in byte? Quest'ultimo è letteralmente lo spazio di memoria che occupa un programma, quindi per me sembra più logico. Per esempio. la risposta di CJam è la più breve in termini di caratteri, ma se si considera la sua dimensione (326 a causa dell'unicode) non è nemmeno nella top 5. Quindi mi chiedo, è una convenzione comune nel golf contare i caratteri anziché i byte?
freddieknets,

Risposte:


3

CJam, 62 caratteri

"ḡꬼ쏉壥떨ሤ뭦㪐ꍡ㡩折量ⶌ팭뭲䯬ꀫ郯⛅彨ꄇ벍起ឣ莨ຉᆞ涁呢鲒찜⋙韪鰴ꟓ䘦쥆疭ⶊ凃揭"2G#b129b:c~

Stack Exchange è incline a eliminare caratteri non stampabili, ma copiare il codice da questo incolla e incollarlo nell'interprete CJam funziona bene per me.

Come funziona

Dopo aver sostituito la stringa Unicode con una stringa ASCII, viene eseguito il seguente codice:

" Push 85, read the integers from STDIN and collect everything in an array.               ";

85l~]

" Convert the array of base 4**17 digits into and array of base 2 digits.                 ";

4H#b2b

" Split into chunks of length 93 and 84.                                                  ";

93/~

" Do the following 611 times:

    * Rotate array A (93 elements) and B one element to the left.
    * B[83] ^= B[14]
    * T = B[83]
    * B[83] ^= B[0] & B[1] ^ A[23]
    * A[92] ^= A[26]
    * Rotate T ^ A[92] below the arrays.
    * A[92] ^= A[0] & A[1] ^ B[5].                                                        ";

{(X$E=^:T1$2<:&^2$24=^+\(1$26=^_T^@@1$2<:&^3$5=^+@}611*

" Discard the arrays and collects the last 177 generated bits into an array.              ";

;;]434>

" Convert the into an integer and check if the result is 922 ... 593.                     ";

2b9229084211442676863661078230267436345695618217593=

Questo approccio utilizza Bivium-B (vedi analisi algebrica di cifre simili al trivio ), una versione indebolita del codice di flusso Trivium .

Il programma utilizza la sequenza di numeri interi come stato iniziale, aggiorna lo stato 434 volte (354 round raggiungono la piena diffusione) e genera 177 bit di output, che confronta con quelli della sequenza corretta.

Poiché la dimensione dello stato è precisamente 177 bit, ciò dovrebbe essere sufficiente per identificare in modo univoco lo stato iniziale.

Esempio di esecuzione

$ echo $LANG
en_US.UTF-8
$ base64 -d > block.cjam <<< IgThuKHqrLzsj4nlo6XrlqjhiKTrrabjqpDqjaHjoanmipjvpb7itozuoIDtjK3rrbLul7bkr6zqgKvvjafpg6/im4XlvajqhIfrso3uprrotbfvmL/hnqPojqjguonhhp7mtoHujLPuipzlkaLpspLssJzii5npn6rpsLTqn5PkmKbspYbnlq3itorlh4Pmj60iMkcjYjEyOWI6Y34=
$ wc -m block.cjam
62 block.cjam
$ cjam block.cjam < block.secret; echo
1
$ cjam block.cjam <<< "1 2 3 4 5"; echo
0

6

CJam, 91 caratteri

q~]KK#bD#"᫖࿼듋ޔ唱୦廽⻎킋뎢凌Ḏ끮冕옷뿹毳슟夫΢眘藸躦䪕齃噳卤"65533:Bb%"萗縤ᤞ雑燠Ꮖ㈢ꭙ㈶タ敫䙿娲훔쓭벓脿翠❶셭剮쬭玓ୂ쁬䈆﹌⫌稟"Bb=

Stack Exchange è incline a eliminare caratteri non stampabili, ma copiare il codice da questo incolla e incollarlo nell'interprete CJam funziona bene per me.

Come funziona

Dopo aver sostituito la stringa Unicode con numeri interi (considerando le cifre dei caratteri dei numeri di base 65533), viene eseguito il seguente codice:

" Read the integers from STDIN and collect them in an array.                               ";

q~]

" Convert it into an integer by considering its elements digits of a base 20**20 number.   ";

KK#b

" Elevate it to the 13th power modulus 252 ... 701.                                        ";

D#
25211471039348320335042771975511542429923787152099395215402073753353303876955720415705947365696970054141596580623913538507854517012317194585728620266050701%

" Check if the result is 202 ... 866.                                                      ";

20296578126505831855363602947513398780162083699878357763732452715119575942704948999334568239084302792717120612636331880722869443591786121631020625810496866=

Dato che 13 è coprime al totale del modulo (il totale è segreto, quindi dovrai solo fidarti di me), basi diverse genereranno risultati diversi, cioè la soluzione è unica.

A meno che qualcuno non possa sfruttare il piccolo esponente (13), il modo più efficace di rompere questo blocco è quello di fattorizzare il modulo (vedi problema RSA ). Ho scelto un numero intero a 512 bit per il modulo, che dovrebbe resistere a 72 ore di tentativi di fattorizzazione.

Esempio di esecuzione

$ echo $LANG
en_US.UTF-8
$ base64 -d > lock.cjam <<< cX5dS0sjYkQjIgHuiJHhq5bgv7zrk4velOWUse6zjuCtpuW7veK7ju2Ci+uOouWHjOG4ju+Rh+uBruWGleyYt+u/ueavs+6boOyKn+Wkq86i55yY6Je46Lqm5KqV6b2D5Zmz75Wp5Y2kIjY1NTMzOkJiJSIB6JCX57ik4aSe74aS6ZuR54eg4Y+G44ii6q2Z44i244K/5pWr5Jm/5aiy7ZuU7JOt67KT7rO26IS/57+g4p2275+K7IWt5Ymu7Kyt546T4K2C7IGs5IiG77mM4quM56ifIkJiPQ==
$ wc -m lock.cjam
91 lock.cjam
$ cjam lock.cjam < lock.secret; echo
1
$ cjam lock.cjam <<< "1 2 3 4 5"; echo
0

Ho pubblicato una nuova versione da quando ho dimenticato di rimuovere un personaggio non necessario dal primo. La sequenza segreta è sempre la stessa, quindi puoi provare a decifrare una delle due.
Dennis,

Cordiali saluti, sto interrompendo il mio tentativo di factoring. msieve si è fissato un limite di tempo di 276 ore, ma era solo per costruire la base dei fattori. In quel momento found 1740001 rational and 1739328 algebraic entries; da allora ha avuto quasi 100 ore per elaborarli e rapporti sieving in progress b = 46583, 0 complete / 0 batched relations (need 44970493).
Peter Taylor,

@PeterTaylor: Sembra che 512 bit siano stati eccessivi. Stavi cercando di fattorizzare il numero intero nell'altra mia risposta o in questa?
Dennis,

Oh, oops. Sì, altro.
Peter Taylor,

4

Python - 128

Proviamo questo:

i=input()
k=1050809377681880902769L
print'01'[all((i>1,i[0]<i[4],k%i[0]<1,k%i[4]<1,i[4]-i[3]==i[3]-i[2]==i[2]-i[1]==i[1]-i[0]))]

(Si aspetta che l'utente inserisca 5 numeri separati da virgola, ad es 1,2,3,4,5.)


3
32416190039,32416190047,32416190055,32416190063,32416190071
Martin Ender,

Wow, è stato veloce! Hai ragione! E io sono fuori.
Falko,

3
A proposito, questo non è in realtà valido, perché i tuoi cinque numeri interi non rientrano in un numero intero a 32 bit.
Martin Ender,

4

Java: 468

L'input è dato come k(int[5]). Cauzioni anticipate se non equidistanti. Altrimenti, ci vuole un po 'per capire se tutti e dieci gli hash sono corretti. Per numeri grandi, "un po '" può significare dieci secondi o più, quindi potrebbe dissuadere i cracker.

//golfed
int k(int[]q){int b=q[1]-q[0],i,x,y,j,h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,998860524,888446062,1833324980,1391496617,2075731831};for(i=0;i<4;)if(q[i+1]-q[i++]!=b||b<1)return 0;for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));for(i=0;i<5;i++){for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));if(x!=h[i*2]||y!=h[i*2+1])return 0;}return 1;}int m(int a,int b,int c){long d=1;for(;b-->0;d=(d*a)%c);return (int)d;}

// line breaks
int k(int[]q){
    int b=q[1]-q[0],i,x,y,j,
    h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,
                  998860524,888446062,1833324980,1391496617,2075731831};
    for(i=0;i<4;)
        if(q[i+1]-q[i++]!=b||b<1)
            return 0;
    for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));
    for(i=0;i<5;i++){
        for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));
        if(x!=h[i*2]||y!=h[i*2+1])
            return 0;
    }
    return 1;
}
int m(int a,int b,int c){
    long d=1;for(;b-->0;d=(d*a)%c);
    return (int)d;
}

1
Il codice si blocca se la sequenza aritmetica di input sta scendendo. O almeno, richiede molto tempo. Il che mi fa pensare che il codice segreto stia ascendendo ...
Keith Randall,

3
@KeithRandall Oops. Aggiungiamo quattro byte per fare in modo che le sequenze discendenti impieghino un tempo insolitamente breve , rafforzando ulteriormente la tua convinzione.
Geobits il

4

Java: 342

int l(int[]a){String s=""+(a[1]-a[0]);for(int b:a)s+=b;char[]c=new char[11];for(char x:s.toCharArray())c[x<48?10:x-48]++;for(int i=0;i<11;c[i]+=48,c[i]=c[i]>57?57:c[i],i++,s="");for(int b:a)s+=new Long(new String(c))/(double)b;return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;}

Ecco un armadietto basato su stringhe che dipende sia dal conteggio dei caratteri di input sia dall'input specifico. La sequenza potrebbe essere basata su riferimenti oscuri alla cultura pop. Divertiti!

Un po 'non golfato:

int lock(int[]a){
    String s=""+(a[1]-a[0]);
    for(int b:a)
        s+=b;
    char[]c=new char[11];
    for(char x:s.toCharArray())
        c[x<48?10:x-48]++;
    for(int i=0;i<11;c[i]+=48,
                     c[i]=c[i]>57?57:c[i],
                     i++,
                     s="");
    for(int b:a)
        s+=new Long(new String(c))/(double)b;
    return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;
}

2
8675309? 90210?
Malachi,

1
@Malachi Due riferimenti in sospeso, senza dubbio, ma non posso né confermare né negare la loro applicabilità a questo esercizio.
Geobits il

lol, non ho ancora capito come funziona questa sfida, potrei provarci più tardi quando sarò a casa.
Malachi,

1
Il termine iniziale è -8675309, delta è 5551212.
Peter Taylor,

@PeterTaylor Ben fatto :)
Geobits il

4

Python, 147

Modifica: versione più breve basata sul commento di Dennis. Ho aggiornato anche la sequenza per evitare la perdita di informazioni.

def a(b):
    c=1
    for d in b:
        c=(c<<32)+d
    return pow(7,c,0xf494eca63dcab7b47ac21158799ffcabca8f2c6b3)==0xa3742a4abcb812e0c3664551dd3d6d2207aecb9be

Basato sul discreto problema del logaritmo che si ritiene non sia crackabile, tuttavia il primo che sto usando è probabilmente troppo piccolo per essere sicuro (e potrebbe avere altri problemi, non lo so). E puoi forzarlo bruscamente, naturalmente, poiché le uniche incognite sono due numeri interi a 32 bit.


I logaritmi discreti sono molto più difficili di quanto pensassi. Il mio cracker è stato a questo per 26 ore. Mi arrendo.
Dennis,

È possibile risolvere il problema dei segni inizializzando c=1, calcolando c=(c<<32)+de modificando la costante di conseguenza.
Dennis,

3

Javascript 125

Questo dovrebbe essere rotto abbastanza rapidamente. Seguirò con qualcosa di più forte.

function unlock(a, b, c, d, e)
{
    return (e << a == 15652) && (c >> a == 7826) && (e - b == d) && (d - c - a == b) ? 1 : 0;
}

6
0, 3913, 7826, 11739, 15652
Martin Ender,

sì, l'hai capito :)
rdans,

3

Ruby, 175

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
p a[2]*(a[1]^a[2]+3)**7==0x213a81f4518a907c85e9f1b39258723bc70f07388eec6f3274293fa03e4091e1?1:0

A differenza dell'uso di un hash crittografico o srand, questo è decisamente unico (il che è un leggero indizio). Prende cinque numeri tramite STDIN, delimitati da qualsiasi carattere non numerico, non newline o caratteri. Uscita su STDOUT.


Sì, ho dimenticato che erano firmati.
istocratico,

2
622238809,1397646693,2173054577,2948462461,3723870345(la mia ipotesi precedente ha avuto un errore, ma questo è stato testato). Non penso che questo sia valido, perché l'ultimo numero non rientra in un numero intero a 32 bit con segno.
Martin Ender,

3

GolfScript (116 caratteri)

Accetta input come numeri interi separati da spazio.

~]{2.5??:^(&}%^base 2733?5121107535380437850547394675965451197140470531483%5207278525522834743713290685466222557399=

2
-51469355 -37912886 -24356417 -10799948 2756521
Dennis,

Bel lavoro. Hai sfruttato il piccolo esponente?
Peter Taylor,

2
No, ho scomposto il modulo. Ci sono voluti solo 13 secondi usando il setaccio quadratico multiplo polinomiale e PyPy di ​​primo.
Dennis,

In tal caso, potrei anche abbandonare il mio attuale golf utilizzando un modulo espresso in modo compatto. Se il risultato deve essere qualcosa come 1024 bit per essere sicuro dal factoring, allora anche usando una rappresentazione base-256 sarà troppo lungo.
Peter Taylor,

Spero di no. La mia risposta usa la stessa idea della tua, ma con un modulo da 512 bit e un esponente ancora più piccolo (13). Dato il limite di 72 ore, potrebbe essere sufficiente ...
Dennis,

3

C 459 byte

RISOLTO DA Tyilo - LEGGI EDIT SOTTO

int c (int* a){
int d[4] = {a[1] - a[0], a[2] - a[1], a[3] - a[2], a[4] - a[3]};
if (d[0] != d[1] || d[0] != d[2] || d[0] != d[3]) return 0;
int b[5] = {a[0], a[1], a[2], a[3], a[4]};
int i, j, k;
for (i = 0; i < 5; i++) { 
for (j = 0, k = 2 * i; j < 5; j++, k++) {
k %= i + 1;
b[j] += a[k];
}
}
if (b[0] == 0xC0942 - b[1] && 
b[1] == 0x9785A - b[2] && 
b[2] == 0x6E772 - b[3] && 
b[3] == 0xC0942 - b[4] && 
b[4] == 0xB6508 - b[0]) return 1;
else return 0;
}

Abbiamo bisogno di qualcuno che scriva una soluzione C, no? Non sto impressionando nessuno per la lunghezza, non sono un golfista. Spero che sia una sfida interessante!

Non credo che ci sia un modo ovvio per risolverlo, e attendo con impazienza tutti i tentativi! So che questa soluzione è unica. Offuscamento molto minimo, principalmente per soddisfare i requisiti di lunghezza. Questo può essere testato semplicemente:

int main(){
    a[5] = {0, 0, 0, 0, 0} /* your guess */
    printf("%d\n", c(a));
    return 0;
}

PS C'è un significato per a[0] come numero a sé stante, e mi piacerebbe vedere qualcuno che lo sottolinea nei commenti!

MODIFICARE:

Soluzione: 6174, 48216, 90258, 132300, 174342

Una nota sul crack:

Anche se questo non è il metodo usato (vedi i commenti), mi è capitato di rompere il mio codice con una forza bruta molto semplice. Capisco ora che è di vitale importanza aumentare i numeri. Il codice seguente può decifrare qualsiasi cifra a cui upper_boundè associato un limite superiore noto a[0] + a[1] + a[2] + a[3] + a[4]. Il limite superiore nella cifra sopra è 457464, che può essere derivato dal sistema di equazioni b[]e da alcune elaborazioni dell'algoritmo. Si può dimostrare che b[4] = a[0] + a[1] + a[2] + a[3] + a[4].

int a[5];
for (a[0] = 0; a[0] <= upper_bound / 5; a[0]++) {
    for (a[1] = a[0] + 1; 10 * (a[1] - a[0]) + a[0] <= upper_bound; a[1]++) {
        a[2] = a[1] + (a[1] - a[0]);
        a[3] = a[2] + (a[1] - a[0]);
        a[4] = a[3] + (a[1] - a[0]);
        if (c(a)) {
            printf("PASSED FOR {%d, %d, %d, %d, %d}\n", a[0], a[1], a[2], a[3], a[4]);
        }
    }
    printf("a[0] = %d Checked\n", a[0]);
}

Con a[0] = 6174, questo ciclo ha rotto il mio lavoro in poco meno di un minuto.


6
Soluzione: 6174, 48216, 90258, 132300, 174342.
Tyilo,

Wow, è stato veloce. Ben fatto. Bruto rinforzato o hai trovato qualcosa di intelligente che mi mancava?
BrainSteel,

Ho usato la valutazione simbolica di Mathematica in questo modo: ghostbin.com/paste/jkjpf screenshot: i.imgur.com/2JRo7LE.png
Tyilo

Per quanto riguarda il montaggio: ho fatto praticamente la stessa cosa, ma ho spostato la tomaia a 500k. Ottenne la risposta e vide che Tyilo l'aveva già pubblicata :(
Geobits il

@Geobits È un'ipotesi sorprendentemente accurata. Avrei dovuto aggiungere altri 0 alle estremità di quei numeri.
BrainSteel,

3

Mathematica 80 67

f=Boole[(p=NextPrime/@#)-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&

In esecuzione:

f[{1,2,3,4,5}] (* => 0 *)

Probabilmente abbastanza facile da decifrare, potrebbe anche avere più soluzioni.

Aggiornamento: golf migliorato seguendo le indicazioni di Martin Büttner. La funzionalità della funzione e del tasto non è cambiata.


@ MartinBüttner Migliorare le risposte per ottenere un punteggio più alto quando le craccate. Smart; P
Tyilo,

Eh, risulta che ho saltato il paragrafo sul punteggio per la contro sfida. Ho pensato che fosse solo per il gusto di farlo senza alcun punteggio. Anche se non penso che avrebbe senso accorciare le soluzioni che voglio decifrare perché ciò ridurrebbe il mio punteggio.
Martin Ender,

4
{58871,5592,-47687,-100966,-154245}
freddieknets il

@freddieknets Non è la soluzione che ho usato durante la sua creazione. Non sapevo che NextPrimepotesse restituire valori negativi. Come l'hai trovato?
Tyilo,

Quindi la tua chiave non è unica: p. Ho appena eseguito alcuni test - in realtà non ci sono molti numeri in cui NextPrime [#] - # restituisce 31, quindi è un modo semplice per decifrarlo.
freddieknets,

2

Python27, 283 182

Va bene, sono molto fiducioso nel mio armadietto, tuttavia è piuttosto lungo poiché ho aggiunto i calcoli "difficili da invertire" all'input, per renderlo bene - difficile da invertire.

import sys
p=1
for m in map(int,sys.argv[1:6]):m*=3**len(str(m));p*=m<<sum([int(str(m).zfill(9)[-i])for i in[1,3,5,7]])
print'01'[p==0x4cc695e00484947a2cb7133049bfb18c21*3**45<<101]

modifica: Grazie a Colevk per l'ulteriore golf. Mi sono reso conto durante la modifica che c'era un bug e un difetto nel mio algoritmo, forse avrò più fortuna la prossima volta.


5
Questo è invariante sotto il riordino degli argomenti, quindi non è un armadietto valido.
Peter Taylor,

Inoltre, sospetto che il codice come pubblicato sia errato: la chiave 121174841 121174871 121174901 121174931 121174961funziona, ma solo se l'elenco [1,3,5,7]alla riga 7 viene sostituito [1,3,5,7,11].
Ilmari Karonen,

Accidenti, sì, stavo solo aggiustando il mio errore di battitura, durante il quale ho fatto un errore cruciale nel mio algoritmo, lasciandolo molto facile da decifrare: |
stokastic il

In realtà, trovare e correggere il bug era la parte difficile; dato il tuo algoritmo, considerare la costante era una cosa ovvia da provare.
Ilmari Karonen,

2

Mathematica 142 146

EDIT : chiave non era unica, aggiunti 4 caratteri, ora lo è.

n=NextPrime;
f=Boole[
    FromDigits /@ (
        PartitionsQ[n@(237/Plus@##) {1, ##} + 1] & @@@ 
            IntegerDigits@n@{Plus@##-37*Log[#3],(#1-#5)#4}
    ) == {1913001154,729783244}
]&

(Spazi e newline aggiunti per leggibilità, non conteggiati e non necessari).

Uso:

f[1,2,3,4,5]   (* => 0 *)

1
Termine iniziale 256208, delta -5.
Peter Taylor,

Dang, quindi non è unico, in quanto questa non è la mia chiave originale. Hai avuto forza bruta?
freddieknets,

Provalo, potrei aver fatto un errore perché non ho accesso a Mathematica per testare. Ogni fase utilizza la forza bruta, ma non è molto tempo per il computer. L'approccio è quello di lavorare all'indietro verso l'output di IntegerDigitse quindi fattore per ottenere candidati per il termine iniziale e il delta.
Peter Taylor,

Ma non è possibile che questo approccio sia unico. Il secondo dei cinque input viene utilizzato solo in una somma a cui viene passato NextPrime; se lo variamo di più o meno uno, almeno uno di questi darà lo stesso primo successivo.
Peter Taylor

sì, ma per una sequenza aritmetica -come è l'input richiesto- doveva essere unico.
freddieknets,

1

Craccato da @Dennis in 2 ore


Solo uno semplice per iniziare le cose - mi aspetto pienamente che questo verrà rapidamente risolto.

Pyth , 13

h_^ZqU5m-CGdQ

Accetta input separato da virgole su STDIN.

Eseguilo in questo modo (-c significa prendere il programma come argomento della riga di comando):

$ echo '1,2,3,4,5' | python3 pyth.py -c h_^ZqU5m-CGdQ
0

Risolto il problema con il programma: non avevo capito le specifiche.

Questo linguaggio potrebbe essere troppo esoterico per questa competizione - Se OP lo pensa, lo rimuoverò.


7
Hai appena dato via questa 1,2,3,4,5è la chiave?
Peter Taylor,

1
Ogni input che ho provato ha restituito 1, hai cambiato 1 e 0 come output?
Tyilo,

Spiacenti, non ho capito la distinzione Output / Return: il programma dovrebbe funzionare ora. Stesso algoritmo sottostante.
isaacg,

3
97,96,95,94,93(Ho appena ucciso il mio punteggio di cracking.)
Dennis il

@Dennis Ben fatto. Il sistema di punteggio cracking deve essere modificato - sta creando alcuni incentivi davvero strani.
isaacg,

1

Lua 105

Sospetto che non passerà molto tempo prima che si rompa, ma eccoci qui:

function f(a,b,c,d,e)
   t1=a%b-(e-2*(d-b))
   t2=(a+b+c+d+e)%e
   t3=(d+e)/2
   print(t1==0 and t2==t3 and"1"or"0")
end

(spazi aggiunti per maggiore chiarezza, ma non fanno parte del conteggio)


3, 7, 11, 15, 19oppure6, 14, 22, 30, 38
Dennis,

@Dennis: purtroppo non è nessuno dei due. Dovrò lavorarci un po 'più tardi per garantire la non unicità.
Kyle Kanos,

t1==0quando Ssta aumentando. Inoltre, entrambe le condizioni sono omogenee; se Sè una soluzione, così è kS.
Dennis,

1

Perl - 256

sub t{($z,$j,$x,$g,$h)=@_;$t="3"x$z;@n=(7,0,split(//,$g),split(//,$h),4);@r=((2)x6,1,1,(2)x9,4,2,2,2);$u=($j+1)/2;for$n(0..$#r+1){eval{substr($t,$j,1)=$n[$n]};if($@){print 0; return}$j+=$r[$n]*$u}for(1..$x){$t=pack'H*',$t;}eval$t;if($@||$t!~/\D/){print 0}}

Ho dovuto inserire molta logica di gestione degli errori e questo può sicuramente essere risolto molto di più. Stamperà un 1quando otterrai i cinque numeri giusti. Si spera che stamperà a 0per tutto il resto (potrebbe essere errori o niente, non lo so). Se qualcuno vuole aiutare a migliorare il codice o giocare a golf di più, sentiti libero di dare una mano!


Chiama con:

t(1,2,3,4,5);

1

Rubino - 130

Basato sul registro a scorrimento a feedback lineare. Input da argomenti della riga di comando.
Dovrebbe essere unico in base alla natura degli LFSR. Indizio: crescente e tutto positivo.

Fornirà ulteriori indizi se nessuno lo risolverà presto.

x=($*.map{|i|i.to_i+2**35}*'').to_i
(9**8).times{x=((x/4&1^x&1)<<182)+x/2}
p x.to_s(36)=="qnsjzo1qn9o83oaw0a4av9xgnutn28x17dx"?1:0

3
Valore iniziale 781783, incremento 17982811
Peter Taylor,

@PeterTaylor Argh ... =)
Vectorized

1

Ruby, 249

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
r=(a[0]*a[1]).to_s(5).tr'234','(+)'
v=a[0]<a[1]&&!r[20]&&(0..3).select{|i|/^#{r}$/=~'%b'%[0xaa74f54ea7aa753a9d534ea7,'101'*32,'010'*32,'100'*32][i]}==[0]?1:0rescue 0
p v

Dovrebbe essere divertente. Chi ha bisogno di matematica?


2
309, 77347, 154385, 231423, 308461ma non credo sia unico.
Martin Ender,

Sì, non lo è. Per lo stesso regex (cioè prodotto dei primi due numeri), trovo anche 103, 232041, 463979, 695917, 927855e 3, 7966741, 15933479, 23900217, 31866955. E sono abbastanza sicuro che ci siano altre regex valide usando ulteriori +s.
Martin Ender,

Scusa, immagino di aver incasinato la stringa di test. Si supponeva che ci fosse una sola regexp con una fattorizzazione unica.
istocrato,

Se vuoi provare a risolverlo, assicurati di prendere in considerazione i quantificatori possessivi. Posso anche creare una regex più grande, equivalente inserendo ()o simili.
Martin Ender,

1

CJam, 49 caratteri

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b[1q~]8H#b%!

Provalo online.

Come funziona

" Push a string representing a base 65536 number and convert it to an integer.            ";

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b

" Prepend 1 to the integers read from STDIN and collect them into an array.               ";

[1q~]

" Convert that array into an integer by considering it a base 2**51 number.               ";

8H#b

" Push the logical NOT of the modulus of both computed integers.                          ";

%!

Il risultato sarà 1 se e solo se il secondo numero intero è un fattore del primo, che è un prodotto di due numeri primi: quello corrispondente alla sequenza segreta e l'altro che non corrisponde a nessuna sequenza valida. Pertanto, la soluzione è unica.

Realizzare un numero intero a 512 bit non è così difficile, ma spero che nessuno sarà in grado di farlo in 72 ore. La mia versione precedente che utilizzava un numero intero a 320 bit è stata interrotta .

Esempio di esecuzione

$ echo $LANG
en_US.UTF-8
$ base64 -d > flock512.cjam <<< IuiFleyYoeijg+SDrOqvs+uEkNaa76a/5b6L4KGG4ZOF76Gi46WE64eu4pSO5JSk5ayj6pGZ5Ji/7Zy64aWw57GD5YO+7I6n6Kuv65aG7qK04byr6aS+6IWO7rSn7YuvIjJHI2JbMXF+XThII2IlIQ==
$ wc -m flock512.cjam
49 flock512.cjam
$ cjam flock512.cjam < flock512.secret; echo
1
$ cjam flock512.cjam <<< "1 2 3 4 5"; echo
0

Ho avuto msieve in esecuzione su di esso per oltre 24 ore, ma poiché il suo limite di tempo autoimposto è 276,51 ore CPU e gli ho dato solo una CPU, non sono ottimista.
Peter Taylor,

0

Javascript 958

Converte gli input in un numero di tipi di dati ed esegue alcune manipolazioni relative a ciascun tipo di dati lungo il percorso. Dovrebbe essere invertito abbastanza facilmente per chiunque impieghi tempo.

function encrypt(num)
{
    var dateval = new Date(num ^ (1024-1) << 10);

    dateval.setDate(dateval.getDate() + 365);

    var dateString = (dateval.toUTCString() + dateval.getUTCMilliseconds()).split('').reverse().join('');

    var result = "";

    for(var i = 0; i < dateString.length; i++)
        result += dateString.charCodeAt(i);

    return result;
}

function unlock(int1, int2, int3, int4, int5)
{
    return encrypt(int1) == "5549508477713255485850495848483249555749321109774324948324410511470" && encrypt(int2) == "5756568477713252485848495848483249555749321109774324948324410511470" && encrypt(int3) == "5149538477713248485856485848483249555749321109774324948324410511470" && encrypt(int4) == "5356498477713256535853485848483249555749321109774324948324410511470" && encrypt(int5) == "5748568477713251535851485848483249555749321109774324948324410511470" ? 1 : 0;
}

5
Bruto costretto:320689, 444121, 567553, 690985, 814417
Tyilo il

@Tyilo Se ti fermi ora, penso che nessun cracker possa battere il tuo punteggio. ;)
Martin Ender,

2
@ MartinBüttner A meno che questo non possa essere giocato a meno di 512 per OP, non credo che conta.
Geobits il

0

C, 239 (Cracked by Dennis)

Vai qui per la mia presentazione aggiornata.

Probabilmente potrebbe essere giocato a golf un po 'più a fondo. Certo, non ho avuto il tempo di dimostrare che la chiave è unica (probabilmente non lo è) ma è decisamente sull'ordine di una collisione dell'hash. Se lo rompi, ti preghiamo di condividere il tuo metodo :)

p(long long int x){long long int i;x=abs(x);
for (i=2;i<x;i++) {if ((x/i)*i==x) return 0;}return 1;}
f(a,b,c,d,e){char k[99];long long int m;sprintf(k,"%d%d%d%d%d",e,d,c,b,a);
sscanf(k,"%lld",&m);return p(a)&&p(b)&&p(c)&&p(d)&&p(e)&&p(m);}

1
Quindi 0 0 0 0 0?
Dennis,

Sospiro che era un bug, ma sì, funziona.
Orby,

Ho aggiornato con una versione corretta che dovrebbe essere un po 'più interessante;)
Orby,

Vedi la versione corretta qui .
Orby,

0

C, 212 di Orby - Cracked

https://codegolf.stackexchange.com/a/36810/31064 di Orby ha almeno due chiavi:

13 103 193 283 373
113 173 233 293 353

Orby chiese il metodo che usavo per decifrarlo. La funzione p controlla se x è primo controllando x%i==0per tutti i tra 2 e x (sebbene usando (x/i)*i==xinvece dix%i==0 ) e restituisce vero se x è un numero primo. La funzione f verifica che tutte le lettere a, b, c, d ed e siano prime. Verifica inoltre se il numero m, una concatenazione delle rappresentazioni decimali di e, d, c, b e a (in tale ordine), è primo. La chiave è tale che a, b, c, d, e e m sono tutti primi.

Green e Tao (2004) mostrano che esistono infinite sequenze aritmetiche di numeri primi per qualsiasi lunghezza k, quindi dobbiamo solo cercare queste sequenze che soddisfano anche il fatto che io sia primo. Prendendo il tempo lungo come delimitato da -9.223372037e + 18 e 9.223372037e + 18, sappiamo che per la stringa concatenata si inserisce in long long, i numeri hanno un limite superiore di 9999. Quindi, usando uno script Python per generare tutto sequenze aritmetiche all'interno di tutti i numeri primi <10000 e quindi verificando se la loro concatenazione inversa è un numero primo, possiamo trovare molte possibili soluzioni.

Per qualche motivo ho trovato falsi positivi, ma i due sopra sono validi secondo il programma. Inoltre, ci possono essere soluzioni in cui e è negativo e il resto è positivo (p usa il modulo di x), ma non le ho cercate.

Le chiavi che ho dato sono tutte sequenze aritmetiche ma la sceneggiatura di Orby non sembra richiedere effettivamente che gli input siano una sequenza aritmetica, quindi potrebbero esserci anche chiavi non valide.


0

MATLAB: apparentemente non valido

Molto semplice, devi solo generare il giusto numero casuale.

function ans=t(a,b,c,d,e)
rng(a)
r=@(x)rng(rand*x)
r(b)
r(c)
r(d)
r(e)
rand==0.435996843156676

Può ancora fuoriuscire, ma non dovrebbe essere un problema.


1
Questo approccio è vietato nei commenti. Se non è menzionato nella domanda, proponi una modifica. Scusate.
Peter Taylor,

@PeterTaylor Immagino di essere fuori allora, lo lascerò qui senza punteggio poiché sono curioso di sapere se qualcuno può trovare un punto debole.
Dennis Jaheruddin,

0

MATLAB (con Symbolic Toolbox), 173 caratteri

Questa non è una voce ufficiale e non conta ai fini del punteggio di cracking di nessuno, ma ti farà impazzire per i diritti di vantarti. ;)

function b=L(S),c=sprintf('%d8%d',S(1),S(2)-S(1));b=numel(unique(diff(S)))==1&&numel(c)==18&&all(c([8,9])==c([18,17]))&&isequal(c,char(sym(sort(c,'descend'))-sym(sort(c))));

La cassetta degli attrezzi simbolica è necessaria solo per gestire la sottrazione di numeri interi grandi.

La forzatura bruta dovrebbe essere un cane, ma se hai familiarità con la serie che comporta, la soluzione è banale.


0

Python 2 (91)

Modificare: questo non è consentito perché l'argomento per l'unicità è probabilistico. Mi arrendo.


s=3
for n in input():s+=pow(n,s,7**58)
print s==0x8b5ca8d0cea606d2b32726a79f01adf56f12aeb6e

Prende liste di numeri interi come input, come [1,2,3,4,5].

Il loop è pensato per operare sugli ingressi in modo fastidioso, lasciando una torre di somme ed esponenti. L'idea è come un log discreto, ma con complicazioni disordinate anziché semplicità matematica. Forse la composizione del modulo è una vulnerabilità, nel qual caso potrei renderlo qualcosa di simile 7**58+8.

Non so davvero come dimostrerei che la mia chiave è l'unica, ma la gamma di uscite è almeno 10 volte più grande della gamma di ingressi, quindi probabilmente? Anche se forse è possibile ottenere solo una piccola parte dei potenziali risultati. Potrei sempre aumentare il numero di cifre al costo dei caratteri. Lascio a te decidere cosa è giusto.

Buon cracking!


0

Mathematica - 72

Versione 2 del mio script, con la stessa chiave di quella prevista per la mia versione 1.

Questo sostanzialmente rimuove i numeri primi negativi per NextPrime.

f=Boole[(p=Abs[NextPrime/@#])-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&

In esecuzione:

f[{1,2,3,4,5}] (* => 0 *)

Supponendo di aver capito correttamente cosa fa il tuo codice, ottengo diverse soluzioni di cui il più piccolo è il termine iniziale 9244115, delta 25.
Peter Taylor,

@PeterTaylor Posso confermare che quello è valido.
Martin Ender,

@PeterTaylor corretto, un'altra chiave è1073743739, 1073886396, 1074029053, 1074171710, 1074314367
Tyilo

0

Python, 86 caratteri

a,b,c,d,e=input()
print 1if(a*c^b*e)*d==0xd5867e26a96897a2f80 and b^d==48891746 else 0

Inserisci i numeri come 1,2,3,4,5.

> python 36768.py <<< "1,2,3,4,5"
0
> python 36768.py <<< "[REDACTED]"
1

Questa non è una richiesta valida; accetta l'input 1,0,1,63021563418517255630720,0.
Dennis,

@Dennis Fixed. Spero sia valido ora.
Spuntino il

1
19960211, 31167202, 42374193, 53581184, 64788175
Dennis,

@Dennis Corretto e fantastico. Penso di essere molto povero in matematica.
Spuntino il

2
@Dennis, 63021563418517255630720non è un numero a 32 bit.
Peter Taylor,


0

CJam, 37 caratteri (rotto)

"煷➻捬渓类ⶥ땙ዶ꾫㞟姲̷ᐂ㵈禙鰳쥛忩蔃"2G#b[1q~]4G#b%!

Provalo online.

Come funziona

Vedi la mia nuova risposta

Esempio di esecuzione

$ echo $LANG
en_US.UTF-8
$ base64 -d > flock.cjam <<< IueFt+Keu+aNrOa4k+exu+K2peuVmeGLtuq+q+Oen+Wnsu6AhMy34ZCC47WI56aZ6bCz7KWb5b+p6JSDIjJHI2JbMXF+XTRHI2IlIQ==
$ wc -m flock.cjam
37 flock.cjam
$ cjam flock.cjam < flock.secret; echo
1
$ cjam flock.cjam <<< "1 2 3 4 5"; echo
0

1
737262825 208413108 3974530688 3445680972 2916831257funziona ma non è una progressione aritmetica. Factored in 3 ore e 20 minuti. I numeri a 512 bit erano apparentemente fattibili in 72 ore per $ 75 su EC2 due anni fa, quindi penso che sarebbe stato sicuro.
Peter Taylor,

@PeterTaylor: restituisce 1, ma gli ultimi tre numeri interi sono maggiori di MAX_INT, quindi non è una chiave valida. Detto questo, 3 h 20 m è piuttosto impressionante. L'algoritmo che stavo usando impiegava 16 ore per un semiprime a 256 bit ...
Dennis,

Ho pensato che ci fossero dei numeri negativi lì dentro da qualche parte perché i delta erano quasi giusti ma non del tutto. Ci penserò io.
Peter Taylor,

1
737262825 208413109 -320436607 -849286323 -1378136039
Peter Taylor,

@PeterTaylor: Questo è quello. Spero che la versione a 512 bit duri più a lungo.
Dennis,

-2

C, 212 (Cracking)

Questa è la stessa idea della mia precedente presentazione , giocata a golf più a fondo, con un bug corretto che ha superato 0,0,0,0,0 (Grazie a Dennis per aver segnalato il bug). Compilare con -std = c99.

#define L long long
p(L x){x=abs(x);for(L i=2;i<x;i++){if((x/i)*i==x)return 0;}return(x>1);}
f(a,b,c,d,e){char k[99];L m;sprintf(k,"%d%d%d%d%d",e,d,c,b,a);sscanf(k,"%lld",&m);
return p(a)&p(b)&p(c)&p(d)&p(e)&p(m);}

Qualsiasi sequenza (aritmetica o no) di numeri primi negativi funzionerà. Due esempi: -7 -37 -67 -97 -127,-157 -127 -97 -67 -37
Dennis

Sì, il mio codice è solo pieno di bug. La risposta che ha dato nitro è sulla falsariga di quello che stavo cercando. Ma bel lavoro sottolineando le risposte più ovvie.
Orby,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.