Rendi la tua lingua * per lo più * inutilizzabile! (Discussione della polizia)


61

Ispirato da questo commento ...

Grazie agli utenti Step Hen , Wheat-Wizard e Dennis per avermi aiutato a consolidare le specifiche di questa sfida prima di inviarla!

Questo è il filo degli sbirri. Per il thread dei ladri, vai qui


In questa sfida , ti viene assegnato il compito di eseguire un codice che lo rende in modo che il tuo linguaggio non soddisfi più i nostri criteri di essere un linguaggio di programmazione. In quella sfida, ciò significa far sì che la lingua non possa più ...

  • Accetta input e output numerici

  • Aggiungi due numeri insieme

  • Verifica se un determinato numero è un numero primo o no.

Questa è una sfida di , in cui ci sono due sfide diverse con due obiettivi diversi: i poliziotti proveranno a scrivere del codice che rende la lingua per lo più inutilizzabile, e i ladri cercheranno di trovare la soluzione nascosta che consente ai poliziotti per recuperare la loro lingua.

Come poliziotto, devi scrivere due frammenti di codice:

  1. Uno che rende la tua lingua per lo più inutilizzabile, ad esempio rimuovendo le funzioni integrate per eseguire input / output e operazioni numeriche. Più funzionalità rimuovi, meglio è. Questo codice non può bloccarsi o uscire. Dovrebbe essere possibile aggiungere il codice alla fine di questo frammento e quel codice verrà valutato . E...

  2. ... uno snippet di codice che accetta come input due numeri interi non negativi, li somma e genera la loro somma. Questo snippet deve funzionare correttamente anche dopo aver eseguito il primo snippet. Quando i due frammenti sono combinati insieme, devono formare un programma completo che aggiunge due numeri o definire una funzione che aggiunge due numeri. Idealmente, questo frammento dovrebbe basarsi su comportamenti molto oscuri, in modo da essere più difficile da trovare.

È possibile scegliere qualsiasi metodo standard di input e output . Tuttavia, devi rivelare esattamente quale formato (input e output) stai utilizzando. Un ladro non può decifrare la tua risposta a meno che non utilizzi lo stesso formato come te.

Dopo aver scritto entrambi questi frammenti, devi pubblicare il primo come risposta, senza rivelare il secondo. La tua risposta dovrebbe contenere tutte le seguenti informazioni:

  • Il primo frammento (ovviamente non il secondo).

  • Lingua (inclusa la versione minore, poiché la maggior parte degli invii si baserà probabilmente su strani casi limite)

  • Formato IO, incluso se si tratta di una funzione o di un programma completo. I ladri devono usare lo stesso formato affinché il loro crack sia valido.

  • Eventuali strani casi limite necessari affinché la tua risposta funzioni. Ad esempio, funziona solo su Linux o richiede una connessione a Internet . Ovviamente, questo è leggermente soggettivo, ma se un poliziotto ha un caso limite estremo che gli impedisce di essere rotto, e poi lo rivela solo dopo essere stato al sicuro, considero questa scarsa sportività. Un potenziale ladro dovrebbe avere tutte le informazioni necessarie per decifrare la tua risposta prima che venga decifrata.

Non è necessario rivelare il conteggio dei byte finché la risposta non è sicura.

Ecco un esempio Per il primo frammento, è possibile inviare il seguente programma Python 3:

Python 3

print=None

Riceve input da STDIN e output su STDOUT

E poi come secondo frammento, potresti scrivere:

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Questo è valido perché prenderà due numeri come input e produrrà la loro somma anche se unisci i due frammenti insieme, ad es.

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Tuttavia, sarà estremamente facile per un ladro trovare una soluzione. Poiché questo sarebbe molto facile da decifrare, potresti provare a patchare questo particolare approccio in questo modo:

import sys
sys.stdout=None
print=None

Tuttavia, anche questo ha una soluzione molto semplice:

del print
a,b=int(input()),int(input())
print(a+b)

Come poliziotto, il tuo obiettivo è rendere la soluzione nascosta il più oscura possibile, per impedire ai ladri di trovarla.

I ladri guarderanno una delle tue risposte e cercheranno di decifrarla. Possono decifrarlo scrivendo qualsiasi snippet valido che potrebbe funzionare come snippet 2 (sommando due numeri insieme dopo che la lingua è diventata per lo più inutilizzabile). Questo non deve essere lo stesso frammento che intendevi inizialmente. Se un ladro incrina la tua risposta, lascerà un commento sulla tua risposta, quindi dovresti modificarlo per indicare che è stato crackato. Se il tuo post è incrinato, dovresti modificare la tua risposta per mostrare la soluzione (snippet 2) che avevi inizialmente previsto. Questa non è una regola in sé , solo un suggerimento amichevole per mantenere il gioco divertente. Tu non devi.

Se una risposta rimane senza crack per un'intera settimana, puoi modificarla nel secondo snippet e indicare che la risposta è ora sicura . Se non lo modifichi dopo che è trascorsa la settimana, altri utenti possono comunque crackarlo fino a quando non lo fai. Se non riveli il tuo secondo frammento, non puoi richiedere punti per la tua risposta o chiamarlo sicuro.

Il vincitore del thread della polizia è la risposta sicura più breve che include entrambi i frammenti , conteggiati in byte, e questa risposta sarà accettata dopo che è trascorso un tempo sufficiente. Non è necessario rivelare il conteggio dei byte finché la risposta non è sicura, poiché il conteggio dei byte è irrilevante per il punteggio fino a quando la risposta non è sicura. Nel caso in cui sia trascorso un tempo sufficiente e nessuna risposta rimanga incrinata, il vincitore sarà la risposta rimasta indecisa per il periodo di tempo più lungo.

Divertiti!

Chiarimenti sulle regole

  • Il primo frammento deve essere eseguito correttamente senza accettare alcun input . Può produrre qualsiasi cosa tu voglia, e questa uscita verrà ignorata - fintanto che dopo aver fatto lo snippet, il secondo snippet verrà eseguito correttamente.

  • Il secondo frammento deve essere effettivamente eseguito affinché la risposta sia valida. Questo significa una risposta come

    import sys
    sys.exit()
    

    non è valido perché non rompe la lingua. Si chiude semplicemente. Allo stesso modo, l'immissione di un ciclo infinito non è valida, poiché il secondo frammento non verrà mai eseguito.

  • Dopo essere sicuro, il tuo punteggio è il conteggio dei byte di entrambi i frammenti .

  • Questo torna a Si prega di rivelare eventuali strani casi limite necessari affinché la vostra risposta funzioni ... La vostra presentazione deve contenere abbastanza informazioni prima di essere rivelata per essere riproducibile dopo essere stata rivelata. Questo significa che se la tua risposta diventa sicura, e poi modifichi: Ecco la mia risposta. Oh ya, a proposito questo funziona solo se lo esegui su Solaris, lo scherzo è su di te! la tua risposta non è valida e verrà eliminata e non considerata idonea alla vincita.

  • Il secondo frammento può arrestarsi in modo anomalo dopo aver emesso la somma, purché l'output sia ancora corretto (ad esempio, se si sceglie di eseguire l'output su STDERR e si ottengono un sacco di informazioni sull'arresto anomalo, ciò non è valido).

  • Non è possibile modificare il codice dopo aver inviato una risposta.

  • Non puoi fare affidamento su funzioni crittografiche come crittografia, funzioni hash, CSPRNG ecc.

Snippet per trovare invii non crackati:


3
Cosa si dovrebbe fare per lingue come C? La concatenazione consente solo un "frammento principale" e qualsiasi logica dovrà andare lì. Ad esempio, se ho int main(){ do_evil_stuff(); }dove dovrebbe andare il codice degli utenti? In una funzione? Dopo tutte le dichiarazioni in main?
Conor O'Brien,

1
Il secondo snippet può essere posizionato in qualsiasi punto del primo snippet?
LegionMammal978,

1
Non so nulla di programmazione, ma questa sfida sembra incredibile,
Pritt Balagopal,

2
Ho modificato il fantastico snippet di jimmy23013 . Sentiti libero di tornare indietro, ma lo stavo usando io stesso per trovare osservazioni e ho pensato che potesse aiutare gli altri.
Dom Hastings,

2
@DomHastings È estremamente utile! Grazie mille :)
DJMcMayhem

Risposte:


2

Gforth 0.7.3 (TIO) , 231 byte [SICURO]

Questo codice ridefinisce come inutili alcuni metodi di output necessari, oltre all'aggiunta e qualcosa di cruciale per dichiarare le funzioni. In bocca al lupo!

: . ;
: dec. ;
: u. ;
: .r ;
: u.r ;
: d. ;
: ud. ;
: d.r ;
: ud.r ;
: emit ;
: type ;
: + postpone 2drop ;
: ; + + + postpone exit reveal postpone [ ;

L'input sarà due numeri interi con segno presi dalla parte superiore dello stack come parametri di funzione. Uscita su STDOUT.

Quindi dovresti riparare il danno fatto e definire una funzione che prende i primi due valori dallo stack e stampa il risultato come intero (non float) su STDOUT senza output aggiuntivo (nessuno spazio finale).

Ecco un modello , se la tua funzione obiettivo è denominata f.

Soluzione:

79 byte

In realtà ho rimosso la immediateparola chiave dalla fine della ridefinizione di ;, quindi era necessario che una risposta la includesse all'inizio. La funzione che ho definito è per lo più equivalente alla definizione interna di ., ma non stampa lo spazio alla fine e l'aggiunta viene eseguita per prima, spostando i numeri nella pila a virgola mobile e viceversa.

immediate : f s>f s>f f+ f>d swap over dabs <<# #s rot sign #> (type) #>> 0 0 ;

Provalo online


1
Questa è una risposta molto bella A questo ritmo, sembra che potrebbe finire per essere l'unica risposta non crackata!
DJMcMayhem

:) Ho combinato un paio di ostacoli diversi. A questo punto, mi chiedo se avrei potuto fare solo uno per migliorare il mio punteggio. Ma è possibile che avere più di uno sia il motivo per cui non è stato ancora crackato.
mbomb007,

21

Haskell, incrinato da Christian Sievers

import Prelude(getLine,print)
a=a

Programma completo, lettura di due numeri interi (inclusi quelli negativi) da stdin e scrittura su stdout.

Ho appena disabilitato Prelude, quindi quasi nulla rientra nell'ambito, quindi ho aggiunto una definizione; ulteriori importazioni sono sintatticamente non valide. Ti ho dato getLinee printperò.


Modificato per aggiungere la mia soluzione originale. Il crack di Christian era diverso, ma sfrutta le stesse caratteristiche di base (puoi ottenere una quantità sorprendente di calcoli accedendo a funzioni che hanno uno zucchero sintattico, anche quando non puoi chiamare nulla incorporato direttamente o addirittura nominare i tipi coinvolti).

import Prelude(getLine,print)
a=a
(x:l)!0=x
(x:l)!n=l!d[0..n]
d[x,y]=x
d(x:l)=d l
x^y=[x..]!y
x+y=f[0..y](x^y)(-((-x)^(-y)))
f[]x y=y
f _ x y=x
f.g= \x->f(g x)
f&0= \x->x
f&n=f.(f&d[0..n])
x*y=((+x)&y)0
x%[]=x
x%('-':s)= -(x%s)
x%(c:s)=x*10+i c%s
i c=l['1'..c]
l[]=0
l(x:s)=1+l s
main=do
 x<-getLine
 y<-getLine
 print((0%x)+(0%y))

Che probabilmente non è comunque super golf, ma qui è più leggibile:

import Prelude(getLine,print)
a=a

-- List indexing
(x : _) !! 0 = x
(_ : xs) !! n = xs !! (sndLast [0..n])

-- sndLast [0..n] lets us decrement a positive integer
sndLast [x, _] = x
sndLast (_ : xs) = sndLast xs

-- Pseudo-addition: right-operator must be non-negative
x +~ y = [x..] !! y

-- Generalised addition by sign-flipping if y is negative
x + y = switch [0..y] (x +~ y) (-((-x) +~ (-y)))
  where switch [] _ empty = empty   -- [0..y] is null if y is negative
        switch _ nonempty _ = nonempty

f . g = \x -> f (g x)

-- compose a function with itself N times
composeN f 0 = \x -> x
composeN f n = f . (composeN f (sndLast [0..n]))

-- multiplication is chained addition
x * y = composeN (+x) y 0

strToNat acc [] = acc
strToNat acc ('-' : cs) = -(strToNat acc cs)
strToNat acc (c : cs) = strToNat (acc * 10 + charToDigit c) cs

charToDigit c = length ['1'..c]

length [] = 0
length (_ : xs) = 1 + length xs

main = do
  x <- getLine
  y <- getLine
  print (strToNat 0 x + strToNat 0 y)


17

Python 2 , Cracked

Implementa l'aggiunta come funzione denominata

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\

Provalo online!

Cosa fa questo?

Per aiutarti un po 'ti spiegherò cosa fa. Questo codice apre il file di origine e verifica se il resto del codice soddisfa i seguenti criteri:

  • Non contiene la stringa import
  • È composto esclusivamente da personaggi &)(,.:[]a`cdfijmonrt~

Se non 1soddisfa nessuno dei due criteri, il limite di ricorsione è impostato nel senso che qualsiasi codice scritto raggiungerà il limite di ricorsione.

Non ci sono trucchi qui, ho scritto una soluzione che utilizza solo questi personaggi e nessuna importazione, non sto facendo nulla di sovversivo, ma dirò che penso che sarà piuttosto difficile da decifrare.

Per farti risparmiare un po 'di tempo ecco un breve elenco di cose utili che non puoi fare con questa limitazione

  • + bene duh,

  • eval/ execNon ti avrei permesso di cavartela

  • Numeri, potrebbero essere più utili di quanto pensi

  • Letterali a corda

  • len

  • =, Nessuna variabile di assegnazione

  • >, <, ==. . . Ti ho lasciato senza confronti

  • *, -, /, %, ^, |, >>, << Gli unici operatori disponibili sono ~e&

  • __foo__, Nessuno di quei metodi di sottolineatura doppia fantasia è consentito.


1
Wow, questo è abbastanza malvagio. Bello!
HyperNeutrino,

Risposta fantastica per dare il via alle cose :)
DJMcMayhem

Hehe, questo potrebbe essere stato ispirato da quella stupida sfida da re della collina che ho provato a precisare in chat quella volta
Stephen

4
Penso che questo sia un crack valido: codegolf.stackexchange.com/a/133209/68942
HyperNeutrino

RE il primo frammento: This code is not allowed to crash or exit.(vedi chat per una discussione al riguardo)
Stephen

12

Python 2 , Cracked

Questa è la quarta iterazione di questa risposta. Ognuna delle ultime risposte è stata decifrata reimpostando la profondità di ricorsione.

Implementa l'aggiunta come funzione denominata

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\

Provalo online!

Cosa fa questo?

Per aiutarti un po 'ti spiegherò cosa fa. Questo codice apre il file sorgente e controlla se il resto del codice è composto esclusivamente da caratteri &)(,.:[]a`cdfijmonrt~

Se fallisce, il limite di ricorsione è impostato nel 1senso che qualsiasi codice scritto colpirà il limite di ricorsione.

Ho anche disabilitato tutti i moduli, quindi non puoi importare nulla.

Non ci sono trucchi qui, ho scritto una soluzione che utilizza solo questi personaggi e nessuna importazione, non sto facendo nulla di sovversivo, ma dirò che penso che sarà piuttosto difficile da decifrare.

Per farti risparmiare un po 'di tempo ecco un breve elenco di cose utili che non puoi fare con questa limitazione

  • + bene duh,

  • eval/ execNon ti avrei permesso di cavartela

  • Numeri, potrebbero essere più utili di quanto pensi

  • Letterali a corda

  • len

  • =, Nessuna variabile di assegnazione

  • >, <, ==. . . Ti ho lasciato senza confronti

  • *, -, /, %, ^, |, >>, << Gli unici operatori disponibili sono ~e&

  • __foo__, Nessuno di quei metodi di sottolineatura doppia fantasia è consentito.

La mia soluzione

Quindi ora che xnor lo ha risolto in un modo in cui sono sufficientemente soddisfatto, sto per rivelare la mia soluzione

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

Sorpresa, sorpresa è un mucchio enorme di incomprensibili. Invece di analizzarlo, esaminerò il modo in cui l'ho realizzato.

Ho iniziato con un algoritmo di addizione piuttosto standard

r,o:(o and f(r^o,r&o<<1))or r

Poi ho usato un trucco bit per bit per rappresentare ^con |, &, ~.

r,o:(o and f((r|o)&~(r&o),r&o<<1))or r

Ho usato un altro trucco bit per liberarmi di |

r,o:(o and f(~(~r&~o)&~(r&o),r&o<<1))or r

Ora tutto ciò che rimane è il <<, non dovrebbe essere troppo difficile, giusto? Beh, preparati per un giro accidentato. Per sostituire il bit-shift ho usato le stringhe per aggiungere uno zero alla fine della sua rappresentazione binaria

r,o:(o and f(~(~r&~o)&~(r&o),int(bin(r&o)[2:]+"0",2)))or r

Questo ha alcuni problemi ma quello principale sta usando l'addizione , quindi ho aggirato questo usando un formato

r,o:(o and f(~(~r&~o)&~(r&o),int("{}0".format(bin(r&o)[2:]),2)))or r

Non ci è permesso usare bin, quindi ho usato la formattazione delle stringhe per convertire in binario.

r,o:(o and f(~(~r&~o)&~(r&o),int("{0:b}0".format(r&o),2)))or r

Poiché i letterali per stringhe sono vietati, devo costruire la stringa {0:b}0con parti realizzate con zecche posteriori e joininsieme.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join(["{","0",":","b","}","0"]).format(r&o),2)))or r

La stringa vuota è abbastanza semplice, puoi semplicemente farlo

`r`[:0]

Gli zeri erano

`0`

e {:}tutti furono presi dai dizionari.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],"b",`dict()`[-1],`0`]).format(r&o),2)))or r

bsembra piuttosto difficile da ottenere, non è nel nostro set di caratteri, quindi come possiamo ottenere un oggetto che ha un bsuo repr? Bene, ecco come: quando usi repruna funzione integrata ottieni qualcosa che assomiglia

<built-in function name>

E questo è da dove avremo il nostro b.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],`min`[1],`dict()`[-1],`0`]).format(r&o),2)))or r

Ora tutto ciò che resta sono numeri, ho solo bisogno di -1, 0, 1 e 2, quindi ecco come li ho rappresentati:

-1 = ~(r&~r)
 0 = r&~r
 1 = []in[[]]
 2 = `~([]in[[]])`[[]in[[]]:]

2 potrebbe effettivamente essere un byte più breve di

```r&~r```.find(`r&~r`)

basato sui suggerimenti di @ Blender nei commenti, ma non ci ho pensato fino a dopo il fatto.

Quindi sostituiamo questi numeri in

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

E questo è il crack.


Questo frammento sembra errore da solo.
ATaco,

@ATaco Credo che questo sia stato discusso in chat ed è stato deciso che andava bene.
Wheat Wizard,

Le regole dichiarano esplicitamente il contrario. "Questo codice non può bloccarsi o uscire."
ATaco,

@ATaco Ecco il messaggio che ha detto che lo avrebbe aggiornato quando ne avesse avuto la possibilità.
Wheat Wizard,


10

C (gcc) Incrinato!

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}

Provalo online!

Ingresso da STDIN e uscita a STDOUT.

Questo funziona senza errori. Hahaha, questo è abbastanza malvagio. L'ho provato solo su gcc di TIO. Come sempre, è necessario aggiungere il codice dopo questo frammento per farlo funzionare :) Il commento è cattivo, non ascoltarlo.

Testato su gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1). Dovrebbe funzionare su qualsiasi sistema Linux.

Soluzione originale

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}
void __attribute__ ((destructor)) dtor() {
    int a,b,c,d;a=b=c=0;
    struct FILE* z = popen("cat", "r");
#define q(x)for(;(c=getc(z))^32&&c^-1;)x=10*x+c-48;
q(a);q(b);
    char*y=calloc(c=a+b,1);
    for(a=0;c;){y[a++]=(48+(c%10));c=c/10;}
    for(b=0;b<a/2;b++){d=y[b];y[b]=y[a-b-1];y[a-b-1]=d;}
    write(1,y,a);
}

@ LegionMammal978 Ah sì
Conor O'Brien,

2
Specifica la tua piattaforma!
Giosuè,

@Joshua Ho aggiunto alcune informazioni
Conor O'Brien,


Bene, __asm__e hai molte funzioni tra cui scegliere :) non pensare che C e C ++ siano buoni nemici qui.
edmz,

10

C (GCC su Linux) (crackato)

Invece di usare stupide tecniche di sandbox per la lettura di file, lo facciamo nel modo giusto - con la whitelisting SECCOMP!

Il tuo compito: implementa l'aggiunta con input da STDIN e output a STDOUT.

#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <syscall.h>
#include <stdio.h>
void sandbox();
__attribute__ ((constructor(0))) int s() {
    close(0);
    close(1);
    close(2);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
}
int main() {
    sandbox();
    syscall(SYS_exit, EXIT_SUCCESS);
}
void sandbox() {
    // Your code here!
}

Provalo online!

Cos'e 'questo!?

Per aiutarti nel tuo compito insormontabile, ti spiego cosa fa questo codice.

__attribute__ ((constructor(0)))assicura che la sfunzione venga eseguita per prima. La funzione chiude tutti i descrittori di file aperti per STDIN, STDOUT e STDERR. Quindi il programma si limita con una whitelist SECCOMP rigorosa, che limita le chiamate di sistema a quanto segue:

read(2)
write(2)
_exit(2)
sigreturn(2)

Pertanto non è possibile aprire nuovi file (o fondamentalmente fare qualcosa). Veniamo quindi al main e chiamiamo il tuo codice, ben racchiuso nella sandboxfunzione.

Alla syscall(SYS_exit, EXIT_SUCCESS);fine è solo per garantire che il programma esca in modo pulito - per impostazione predefinita GCC uscirà con il exit_group(2)quale non è consentito dalla whitelist SECCOMP. Questa funzione di uscita viene chiamata dopo l'esecuzione del codice.

Quindi non hai descrittori di file aperti e non puoi aprire nulla di nuovo. Impossibile, vero? ;)



9

Haskell , incrinato da Ben

main=main--

Provalo online! Questo dovrebbe essere un programma completo che legge due numeri da stdin e invia la somma a stdout.

Ogni programma completo inizia eseguendo la mainfunzione, ma qui mainchiama se stesso e provoca un ciclo infinito. A peggiorare le cose, un commento di linea viene avviato --direttamente dietro la chiamata ricorsiva per evitare di cambiarlo in ad esempio main2e quindi di definirlo per fare la somma.


Soluzione prevista:

main=main--$()
_ --$ _ = do
     x <- readLn
     y <- readLn
     print $ x+y

Provalo online!

--avvia un commento di riga a meno che non possa essere analizzato anche come parte di un operatore. (L'evidenziazione della sintassi sembra non essere a conoscenza di questo fatto.) --$È un valido operatore infix che prende maincome primo argomento e qualche secondo argomento fittizio (). Viene quindi definito per ignorare entrambi gli argomenti e per eseguire l'attività richiesta.



5
puoi semplicemente aggiungere "where main = ..."
michi7x7

+1 per una soluzione Haskell che funziona solo a causa della valutazione pigra di Haskell.
Jules,

8

x86 16 bit in modalità reale Assembly ( Cracked )

_main:
    call l
    cli
    hlt
l:  pop si
    xor ax, ax
    mov bp, cs
    mov es, ax
    mov di, 12
    mov [di], si
    mov [di + 2], bp
    pushf
    mov bp, sp
    or word [bp], 256
    popf

Facile se conosci il trucco.


1
Come stai prendendo l'input? In pila o nei registri? (Inoltre, sembra che questo dovrebbe essere un assembly a 16 bit, ma in tal caso, or [bp], 256non è valido. È supposto che lo sia or WORD PTR [bp], 256?)
Cody Gray

1
Inoltre, dovresti specificare quale processore stai usando; ci sono molte versioni x86 e cloni là fuori, e molte istruzioni indefinite. Se avessi scritto il codice per un "oscuro clone 80186" che per caso aveva un'istruzione indefinita che prendeva qualche argomento e bla bla bla ... Potremmo anche aver bisogno dell'ambiente. 16 bit Windows ha dato una garanzia SS == DS che altri sistemi potrebbero non, ad esempio.
Orion,

1
Hai solo bisogno di specificare quale processore se effettivamente sta usando qualche trucco che funziona solo su un particolare modello (o un particolare generazione). Questo codice non è così, quindi penso che "x86-16" sia sufficiente. Secondo me, più generale è, meglio è. Concordato che la modalità reale o protetta dovrebbe essere specificata, sebbene la presenza hltdell'istruzione (anello 0) implichi fortemente che questa non è modalità protetta.
Cody Gray,

3
@Joshua se non funziona su ogni piattaforma, devi almeno specificare una piattaforma su cui funzionerà, credo. Your submission must contain enough information before being revealed to be reproducible after being revealed
Stephen,

1
@StepHen: la soluzione per decifrare il linguaggio è agnostica della piattaforma una volta specificata la modalità reale x86-16, ma l'I / O non è indipendente dalla piattaforma. Chi lo scoppia può specificare il sistema operativo per il quale è scoppiato. Ho aggiunto tardi l'etichetta _main in modo che qualcuno potesse in teoria fare una pausa quasi agnostica collegandosi contro libc.
Giosuè,

4

Javascript, incrinato

Questa sfida nasce da quella di Grant Davis , ma risolve la soluzione che aveva in mente (che crea un iframe e usa l'iframe window). La soluzione viene eseguita nella console javascript su Chromeabout:blank page e richiede due input()secondi, li somma insieme e console.logil risultato è s. Inserisci il tuo codice dopo:

d=prompt=console=document;new MutationObserver(s=>s.forEach(e=>{t=e.target;t.parentNode.removeChild(t)})).observe(d,{"childList":d, "subtree":d})

In primo luogo, abbiamo clobber prompte consolee impostare la scorciatoia d. Quindi, creiamo un osservatore di mutazione con un callback che rimuove ogni bersaglio mutato. Abbiamo impostato quell'osservatore di mutazione per osservare il documento e notificare childListesubtree modificarlo. Invece del letterale true, usiamo la nostra scorciatoia per il valore di verità document(le specifiche non lo consentono, ma Chrome lo fa).

Dopo aver pubblicato questo, ho realizzato un clobber molto più elegante. La mia soluzione prevista funziona ancora, ma il crack pubblicato non:

 h=document.querySelector("html");h.parentNode.removeChild(h);

Benvenuti nel sito! Sono interessato a vedere quale sarà la soluzione :)
DJMcMayhem


4

Perl 5, incrinato da Ilmari Karonen

$_=<DATA>;
s/[+'{dPz|K.UD!_ iJ;o}e6tjWb7253k@%&Iq4l0AN:?\$8B`Yywn9^pfmZQTF"M#-]//g;
eval;
print@_,$!,pop,shift,<>,eval"@>",$\,@ARGV,eval"@$",$@,eval"@@",$,,eval"@,",$/
__DATA__

L'ingresso è ricevuto su righe separate di STDIN e l'output viene stampato su STDOUT.

Tutto il codice segue il __DATA__ marcatore. Questo utilizza un metodo simile alla soluzione di @ WheatWizard in quanto il codice viene analizzato e vengono rimossi i caratteri inutilizzabili.

Questo è stato testato sulle versioni 5.8, 5.10 e 5.16 e non richiede flag da riga di comando.

Provalo online!


2
Potresti specificare il metodo e il formato di input / output?
Ilmari Karonen,

@IlmariKaronen si scusa, è STDINcon caratteri su linee separate e STDOUT. Aggiungerò questo al corpo principale.
Dom Hastings,


4

Python 3, crackato da zbw

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

Tutti i modelli sono stati eliminati, il che significa che non ci sono builtin disponibili e non si può fare molto altro. Uscita su STDOUT, ingresso da STDIN. Questa è la seconda iterazione di questa risposta dopo che la precedente è stata interrotta da una banale crepa aggiungendo un'istruzione break.


Sono davvero curioso di vedere lo snippet che funziona dopo questo
NickA,

Bene, devi aspettare sette giorni o per una crepa non banale, a seconda di quale
evento si verifichi per


Bene, bene, sfide come queste sono molto difficili da fare bene
pepery

4

APL (ngn-apl) , crackato da ngn

Realizzato in collaborazione con il mio collega Marshall .

Immettere attraverso gli argomenti left e right in +. Cioè il tuo obiettivo è quello di inserire il codice dopo quanto segue, in modo che la tua ultima riga legga ⎕←3+2e trasmetta 5a STDOUT.

+←-←−←⍴←≢←≡←⊥←⊤←⍟←○←⍳←⌹←~←∈←∊←⍷←<←≤←=←≥←>←≠←,←⍪←⌷←⌽←⍉←⊖←{}⋄⍣←∘

Provalo online!

Funziona impostando tutte le funzioni utili alle {}quali accetta uno o due argomenti e restituisce un elenco numerico vuoto. Imposta anche per comporre le funzioni.


Crepa

+←{⌈/⍋⍺⍵1/0}

⍺⍵1/0 replicare 0 dall'argomento sinistro e dall'argomento destro e 1

 ottenere gli indici che ordinerebbero quello (poiché tutti gli elementi sono zero, dà 0 1 2… (a + b)

⌈/ il valore massimo (a + b)


ngn / apl include la possibilità di eseguire JavaScript arbitrario. Non considero valida una soluzione del genere, poiché si tratterebbe quindi di disabilitare JavaScript anziché APL. Esiste davvero un modo valido (sebbene oscuro) per resettare +usando solo APL puro e nessun trucco sporco.
Adám,

3

Python 2 , Cracked

Questa è la seconda iterazione di una risposta che è stata decifrata una volta da @HyperNuetrino usando un metodo che non mi aspettavo. Ora l'ho riparato così speriamo che le uniche soluzioni rimaste debbano rispettare le restrizioni che intendevo.

Implementa l'aggiunta come funzione denominata

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\

Provalo online!


Penso che potrei farlo se ne avessi uno u, ma sono bloccato senza di esso.
Isaacg,

@isaacg Solo per curiosità, cosa vorresti fare u?
Wheat Wizard,

.count. Posso ottenere una stringa fino all'output desiderato, ma non ho modo di prenderne la lunghezza.
Isaacg,

__import__('sys').setrecursionlimit(100)... e nulla è stato effettivamente corretto. Tuttavia, non mi va di pubblicarlo nel thread del ladro, mi viene da imbrogliare. Provalo online
Value Ink


3

Java 8, crackato da @ OlivierGrégoire

Ecco il mio tentativo. Praticamente, l'idea è di sovraccaricare tutti gli spazi dei nomi che è possibile utilizzare per l'output (e riflettere, spero). L'output è destinato a sdout (System.out).

class java {
    public static void main(String[]s){
       //there is no executable code in snippet one.
       //your code here.
    }
    class Class{}
    class Method{}
    class System{}
    class FileDescriptor{}
    class Logger{}
    class Runtime{}
    class Scanner{}
}

La lista nera è in genere un approccio peggiore rispetto alla whitelisting, quindi sono sicuro che è solo una questione di tempo prima che qualcuno si avvicini a un approccio che non ho considerato.


1
Questa non è una classe eseguibile ...
Olivier Grégoire,

1
@ OlivierGrégoire Mi dispiace, ho aggiunto class String{}dopo il test senza rendermi conto che sarebbe stato eliminato main(String[] ...). Dovrebbe funzionare ora
Lord Farquaad,

1
Sì, lo farà, grazie! :) Non cambia il crack che sto per fare, però: p
Olivier Grégoire,

1
Cracked! Mi è davvero piaciuto questo :)
Olivier Grégoire,

1
Stavo guardando qualcosa del genere (mi dispiace è difficile formattare il codice nei commenti), ma penso che la tua soluzione sia molto più pulita:int sum = 0; new Exception("" + sum) { public void printStackTrace() { ClassLoader cl = ClassLoader.getSystemClassLoader(); try { printStackTrace(new PrintStream((PrintStream)cl.loadClass("java.lang.System").getDeclaredField("out").get(null))); } catch (Exception e){} } }.printStackTrace();
Lord Farquaad,

3

cQuents, rotto da Mayube

#|1,1:A

Dovrebbe essere abbastanza facile, ma non lo sai mai.

Il "problema" era che senza C tuo codice hai ricevuto un errore.

La soluzione di Mayube:

#|1,1:A+BC

Ogni elemento nella sequenza è il primo input più la seconda volta la terza (aka 1)

Le mie soluzioni:

#1,1:A+B,C

La sequenza scorre tra il primo input più il secondo input e il terzo input (1). Il primo elemento nel secondo è A+B.

#1,1:A+B+C-C

Simile alla soluzione di Mayube - invece di moltiplicarsi B*C, aggiunge Ce poi sottrae.

Provalo online!

Spiegazione

#|1,1      Append 1 and 1 to the end of the user's input
     :     Set mode to : (sequence 1: if given n, output nth term in sequence; if given no n, output whole sequence)
      A    Each item in the sequence equals the first input

Attualmente, questo programma emette 1, poiché senza input dell'utente, il primo input è il primo 1nell'input predefinito ( #).


I documenti sembrano formulati in modo davvero imbarazzante, non posso per la vita di me capire cosa significhi quando diceDefault input is combined with user input to form the total input, which must align with the expected input (which is based on the highest input requested by the Sequence Definition)
Skidsdev

@Mayube è strano, devo trovare un modo per dirlo correttamente. Fondamentalmente, il tuo input per il programma può essere uguale al più alto input richiesto dalle variabili A,B,C,D,Enel codice. Ad esempio, se in qualsiasi momento hai la variabile Dnel tuo programma, il parser si aspetta che ci siano 4 input, ma se c'è anche un E, il parser si aspetta che ci siano 5 input. Non ci può essere inferiore all'importo previsto. Tuttavia, c'è sempre un ultimo input opzionale n, che viene utilizzato in diversi modi da diverse modalità.
Stephen,

@Mayube lo snippet che ho pubblicato sopra contiene un A, quindi cerca un input. Poiché ce ne sono due, entrambi provenienti da #cui viene specificato l'input predefinito, utilizza il primo come Avalore e il secondo come n.
Stephen,

Quindi se dovessi dare 2 input e aggiungere BC, A sarebbe il primo input, B sarebbe il secondo, C sarebbe 1 e n sarebbe il secondo 1?
Skidsdev,

@Mayube esattamente, scusa per i miei documenti schifosi. TMI: se l'inizio sembrava #1,1(nessuna barra), sarebbe: A come primo 1, B come secondo 1, C come primo input e n come secondo input. Puoi anche fare #1|1, dove A è il primo 1, B è il primo input, C è il secondo input e n è il secondo 1.
Stephen

3

Node.JS versione 7.3.0 (Cracked di Dom Hastings)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();

Inserire il secondo blocco di codice dopo il primo.

Disclaimer: il secondo blocco di codice non funzionerà da solo (senza essere inserito dopo il primo). Se ciò non è consentito, tuttavia, posso modificare il secondo frammento.

Questo è un programma completo. L'uscita è process.stdout(STDOUT), l'ingresso èprocess.argv (argomenti della riga di comando)

Questi sono i miei primi poliziotti e ladri, spero che questa sia una bella sfida :)

Provalo online!


La sfida ha spiegato

Genera una variabile casuale nda 0 a 1e7. Se chiami write con il corretto n, non stampa nulla ma imposta lsu 0 che "sblocca" la funzione di scrittura, consentendoti di stampare qualsiasi cosa. Se provi a chiamare write con una non stringa, ti manda in un ciclo infinito. Se provi a chiamare write con qualcosa di diverso da quello corretto nmentre write è "bloccato", ti manda in un ciclo infinito per evitare di indovinare.

La soluzione prevista

Passa di soppiatto il tipo di che apparentemente controlla le stringhe solo usando un simbolo, che inizia anche con s. Ciò genera un errore nella funzione risultante dalla chiamata eval perché non è possibile aggiungere la stringa "f" a un simbolo. Catturiamo l'errore e usiamo regex per recuperare ndalla traccia dello stack, dove si trova nel nome della funzione. Quindi proviamo a scrivere nche non stampa nulla, ma imposta la variabile "lock" lsu 0 per "sbloccare" la funzione di scrittura. Ora che la funzione di scrittura è sbloccata stampiamo semplicemente la somma.

try{f(Symbol())}catch(e){f(e.stack.match(/f(\d+)/)[1])
f(+p.argv[2]+ +p.argv[3]+"")}


È geniale ... All'inizio ero sulla strada giusta! Grazie per l'allenamento al cervello!
Dom Hastings,

3

RProgN2 , Cracked di Arnold Palmer

"+-/*÷^"{²[[\=};

Scrive su tutti gli operatori matematici, senza alcun modo per ripristinarli. In particolare, li sostituisce con una funzione che rimuove i primi due elementi nella pila.

Provalo online!

Soluzione originale

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=
{     }`d=                                  #Define a function, "d", which returns n-1
 S                                          #Convert the input to a stack, which, as a number, makes a stack of 1 - n.
  ]‘                                        #Duplicate the stack, and pop the top value off it.
    [                                       #Discard the popped'd value.
     L                                      #Get the length of the stack, which now is n-1.
          {   }`i=                          #Define a function, "i", which returns n+1
           0R                               #Get the range of numbers between 0 and n.
             L                              #Get the length of that stack, which is n+1
                  «                    »`+= #Define a function, "+", which takes two numbers, and outputs their sum. We use «» here, because it localises references, instead of globalising them.
                   x=                       #Set the first input to the value of "x", which by default, is x.
                     y=                     #Ditto for y.
                       x{          x}:      #While x is truthy, which in this case, is non-zero.
                         xd                 #Get x - 1
                           `x=              #Set x to it.
                              yi`y=         #And set y to y + 1
                                      y     #Push y to the output. And we're done.

Provalo online!


Sto esaminando la tua documentazione e non riesco a trovare quello che fa il ²simbolo. Vuoi illuminarmi?
Arnold Palmer,

Quella documentazione non è incredibilmente rilevante per RProgN2, e quel simbolo prende i seguenti due concetti [[in questo caso e li avvolge in una funzione @ArnoldPalmer
ATaco


Dang, va molto meglio. Non sapevo degli operatori dello stack, il che sicuramente sarebbe stato utile. Inoltre, sapere come «»creare variabili locali anziché confondere quelle globali sarebbe stato di grande aiuto.
Arnold Palmer,

3

Haskell, 161 144 byte, incrinata da Capinera

{-#OPTIONS_GHC -fth -w#-}
module M where

Input su STDIN, output su STDERR. Aggiungi alla fine del programma.

Modifica: destinato a essere compilato senza ulteriori argomenti GHC, solo il normale ghc --make prog.hs .

Modificato di nuovo per ridurre il conteggio dei byte.

Divertiti!


Quindi non posso farlo, perché la funzione principale non verrà chiamata? main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap

@BlackCap No, perché GHC si aspetta che la mainfunzione sia nel modulo Mainquando non -main-isviene fornito alcun flag.
zbw,

Questo non funziona, ma voglio comunque condividere l'idea
BlackCap il

Lo chiamerò incrinato. Ecco la mia soluzione prevista, scesa a terra. Non funziona su TIO, perché il wrapper non invia l'input al compilatore.
zbw,

Se pubblichi la tua soluzione, la segnerò come crackata.
zbw,

3

Mascarpone , rotto da Ilmari Karonen

[ Make 'i' and 'z' print 'q' ]$
v ['q.]v* 'i<^
v ['q.]v* 'z<^

[ Disable some standard commands ]$
v[]v*   '1<^
v[]v*   '$<^
v[]v*   '@<^
v[]v*   '{<^
v[]v*   '}<^
v[<:]v* '<<^
v[]v*   'v<^$

L'input è costituito da numeri di chiesa su stdio, usando iper incrementare e zper zero. Ad esempio, 2 + 3 sarebbe:

iiziiiz

Con una nuova riga finale

Output dovrebbe essere un numero su stdout, nello stesso formato di stdio. Ad esempio, se la risposta è cinque dovresti produrre:

iiiiiz

(il mascarpone non ha il concetto di numeri)


Soluzione prevista:

: '[/''/'i/'./' /':/',/'>/'!/']/* 'i<^
: '[/':/',/'>/'!/']/* 'z<^
: ,>!
'z.

Non risulta immediatamente dalla documentazione, ma come ha affermato @IlmariKaronen nella sua fessura, i letterali per archi in Mascarpone sono in realtà zucchero sintattico per spingere una sequenza di caratteri.

Ho deliberatamente scritto commenti come [this]$per far sembrare che stia spingendo una corda e la faccio scoppiare subito dopo. Un ingenuo cracker avrebbe potuto provare qualcosa del genere[:,>!]/* spingere una stringa, scambiarla con l'interprete e interpretarla.

Faccio anche finta di far apparire l'interprete che ho lasciato in pila $, ma $è già stato ridefinito in un NOP. Rimani con questo interprete in pila e devi portarlo con te attraverso l'intero programma; attraverso ogni carattere di ogni stringa.


Cracked. E no, non avevo mai sentito parlare di Mascarpone prima di questa sfida.
Ilmari Karonen,

@IlmariKaronen Nuova lingua preferita? Buon lavoro!
BlackCap

2

C # (.NET Core) Cracked di Ilmari Karonen

Anche crackato da Giosuè .

namespace System
{
    class Console
    {
        static void Main()
        {
            //Your code goes here
        }
    }
}

Legge i due valori da stdin e scrive il risultato su stdout. Testato su Windows con Framework versione 3, 4.6 e su TIO .

Ecco il programma completo che avevo previsto.

namespace System
{
    class Console
    {
        static void Main()
        {
            var t = Reflection.Assembly.Load("mscorlib").GetType("System.Console");
            var r = t.GetMethod("ReadLine");
            int a = int.Parse((string)r.Invoke(null, null));
            int b = int.Parse((string)r.Invoke(null, null));
            var w = t.GetMethod("WriteLine", new[] { typeof(int) });
            w.Invoke(null, new object[] { a + b });
        }
    }
}

Provalo online!



codegolf.stackexchange.com/a/133412/14306 Presumo che questa non fosse la soluzione prevista.
Giosuè,

@IlmariKaronen: +1. Questa era la soluzione prevista.
raznagul,

@Joshua: +1 per trovare una soluzione diversa da quella che avevo previsto.
raznagul,

2

GolfScript , incrinato da Dennis

{}' !$%&()*+,-./<=>?@[\]^`|~'':'*~;

Provalo online!

Dopo tutto, questa è una sfida al , quindi perché non provare GolfScript?

Una soluzione valida dovrebbe essere uno snippet che legge due numeri interi dallo stack, li somma e restituisce il risultato nello stack. Il problema è che dovrebbe funzionare anche dopo che il codice sopra ha ridefinito quasi tutti gli operatori GolfScript integrati per non fare assolutamente nulla. Almeno sono rimasto ;intatto, quindi puoi comunque estrarre i valori dallo stack. ;-) Il tuo codice dovrebbe funzionare sull'interprete GolfScript standard, come implementato ad es. Su TIO (vedi link sopra).


La soluzione di Dennis , come la mia , si basa sulla funzione raramente utilizzata di GolfScript che consente il codice Ruby interpolato in stringhe tra virgolette doppie. Usiamo questa funzione per definire un nuovo operatore addizione che funziona esattamente come quello incorporato+ operatore , e quindi chiamarlo.

(Uno dei motivi per cui la funzione di interpolazione Ruby in GolfScript viene utilizzata così raramente è che, stranamente, il codice Ruby interpolato viene eseguito durante l'analisi e il suo output viene memorizzato nella cache dall'interprete GolfScript. Pertanto, se ad esempio si dispone di una stringa con codice Ruby interpolato in un ciclo, il codice verrà eseguito solo una volta prima dell'avvio del programma effettivo e, successivamente, restituirà sempre lo stesso valore su ogni iterazione del ciclo. Puoi aggirare il problema usando la stringa eval per rinviare l'analisi, ma ciò rende la sintassi già scomoda ancora di più brutto e dettagliato, e in ogni caso, per questa sfida che ho disabilitato l'operatore eval è una cosa che questa funzione in realtà fa abbastanza bene e in modo pulito.)~ , ma risulta che la definizione di nuovi operatori GolfScript integrati



Cracked. Alla fine ho capito cosa stavo facendo di sbagliato.
Dennis,

@Dennis: Sì, questa volta l'hai inchiodato. FWIW, la mia soluzione prevista era "#{var'_','gpush a+b'.cc2}";_, che funziona esattamente come la tua tranne per essere più corta di qualche byte.
Ilmari Karonen,

2

Node.js v8.2.0, crackato da Dom Hastings

let mess = ctx => f => new Proxy (f, {
  has: (t, p) => p in t || p in ctx
, get: (t, p) => {
    let k = p in t? t[p]: ctx[p];

    if (k instanceof Function) return (
      function fetch (_k) {
        return mess (ctx) ( x => ( q => q instanceof Function
                                      ? fetch (q)
                                      : t (q)
                                  ) ( _k(x) )
                          )
      })(k);

    return k;
  }
});

with (mess (global) (x => x)) {
  dot   = f => a => b => f(a(b))
  ap    = f => g => x => f (x) (g (x))
  flip  = f => x => y => f (y) (x)
  Const = a => b => a
  id    = x => x
  num   = n => n (x => x + 1) (0)
  log   = console.log

  let x = flip (Const . id . id)
    , y = flip (Const . id . id . id)
  for (let i = 0; i < process.argv[2]; i++) x = ap (dot) (x)
  for (let i = 0; i < process.argv[3]; i++) y = ap (dot) (y)
  process.argv = [];

  logic = x => y => /* Your code here */;

  log . id . num ( logic (ap (dot) (x))
                         (f => z => (( y(flip (id) . id . flip (dot (id)) (f)) ) (Const (z))) (id) )
                 );
}

Devi implementare la logicfunzione. Input è l'argomento fornito (da stdin), output è qualunque cosa restituisca la tua funzione (viene stampata su stdout).


La mia chiesa del codice codifica i numeri dall'input. Il resto del codice è lì solo per intimidirti.
La funzione di disordine fa qualche trucco per implementare la notazione senza punti ( a . b == dot (a) (b)), che uso principalmente per aggiungere . id .a luoghi casuali, che non fa nulla, ma confonderà chiunque non abbia familiarità con la programmazione funzionale.
La trasformazione applicata ai numeri prima che li passi alla logicfunzione è x+1e y-1, che aggiunge fino a 0, quindi è un altro NOP da aggiungere all'oscurità.

La soluzione prevista era:

logic = x => y => f => z => x (f) (y (f) (z))


@DomHastings Non è la soluzione prevista, ma dirò che puoi, purché il programma si arresti senza eccezioni e non stampi caratteri aggiuntivi sull'output
BlackCap

Ho appena pubblicato un'alternativa! (Puoi vedere la mia soluzione precedente nella storia di quella risposta però!)
Dom Hastings,

Oh wow, ero lontano ... Comunque è meglio del mio primo tentativo molto economico! Grazie per il puzzle!
Dom Hastings,

2

Inform 7 , incrinato da Ppperry

For reading a command: rule fails.

[Your code here.]

L'ingresso deve essere digitato dal giocatore come un comando interattivo, ad esempio add 17 to 25o sum 17 25. Sei libero di scegliere la forma esatta del comando da inserire, purché includa due numeri. La somma dei numeri (ad es. 42) Dovrebbe essere stampata in risposta al comando.

La sfida, ovviamente, è farlo mentre l'intera attività di "lettura di un comando" viene sostituita da una no-op. Esistono probabilmente diversi modi per risolvere questo problema, ma almeno dovrebbe richiedere una certa familiarità con la lingua. Quello che mi è venuto in mente è in realtà abbastanza semplice, anche se un po 'inaspettato.

Ho testato la mia soluzione nell'IDE GNOME Inform 7, versione 6L38 , su Ubuntu Linux. La soluzione prevista funziona su entrambi i back-end Glulx e Z-machine e dovrebbe funzionare anche su altre versioni recenti di Inform 7. Si noti che (senza una soluzione adeguata) il codice sopra farà sì che l'interprete si occupi del ciclo quando tenta di leggere un comando; l'interprete Z-machine sembra non rispondere quando questo accade e non può essere fermato dall'IDE, quindi consiglio di usare Glulx per i test.


incrinato , e nel caso te lo stessi chiedendo, non avevo mai sentito parlare prima di questa sfida
pppery

2

CPython 3 (di nuovo), incrinato da Sisifo

import sys,os,functools
def p(f,e,a,_=os._exit):
 if e == "c_call":_(1)
sys.setprofile(p)

Puoi fare tutto quello che vuoi - purché non sia implementato in C. Questo significa no print, no input- tutti colpiranno la _(1)linea e termineranno. Input da STDIN con i numeri su due righe separate, output su STDOUT. Mi chiedo quanto durerà ... Mi ci è voluto un po 'per trovare il secondo frammento funzionante dopo aver escogitato questo trucco disabilitante. Specificare esplicitamente Cpython per evitare di essere crackati in base a qualche implementazione alternativa di sys.setprofile.


Cracked. Ho ben poca idea del perché funzioni.
Sisifo,

Immagino di poterlo chiedere ora: perché functools?
Dennis,

@Dennis Perché sispyphus ha scoperto una scappatoia, non la soluzione voluta
pepery

@Sisyphus Il tuo crack è stato segnalato come un bug in pitone
pepery il

2

Java 8 ( Cracked )

Secondo tentativo. Questa volta ho investito due minuti di test.

static {

    try {

        System.setIn(null);
        System.setOut(null);
        System.setErr(null);

        for (Method m : System.class.getMethods()) {

            m.setAccessible(false);

        }

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                if (p.getName().equals("createSecurityManager")) throw new SecurityException();
                if (p.getActions().startsWith("read")) throw new SecurityException();

            }

        };

        System.setSecurityManager(mngr);

        // Your code goes here.

    } catch (Throwable t) {

    }

}

La maggior parte delle cose dovrebbe essere coperta.


1
Vorresti per favore racchiuderlo in una classe con le importazioni appropriate? È il tipo di sfida in cui questi piccoli cambiamenti possono fare o rompere una voce. Ho avuto diverse soluzioni per questo così com'è, ma ciò si riduce drasticamente se lo racchiudi semplicemente in una classe / interfaccia. Inoltre, il formato per rimuovere tutte quelle linee mentre sarebbe bello per noi, lettori.
Olivier Grégoire,

Ecco una risposta incrinata usando esattamente il tuo codice. E un +1 perché sembra che me ne sia dimenticato. Scusate.
Olivier Grégoire,

Le chiamate #setAccessible (false) non fanno nulla.
Nevay,

1

Python 2 incrinato

import sys,hashlib
c=open(__file__).read().split()[-1]
if c!='#'and hashlib.sha256(c).hexdigest()!='e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843':sys.exit() #

Provalo online!

Premetto questo dicendo che questa risposta è una mossa a scatti, intesa come una risposta dal limite inferiore.


Ispirato dalle risposte di Wheat Wizard e HyperNeutrino .

Lo snippet legge il file di origine e rifiuta di continuare se l'ultimo pezzo di codice separato da spazi bianchi non viene inserito e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843.

EDIT : modificato leggermente in risposta a questo commento . Il problema principale non cambia, qualsiasi tentativo di crack non viene invalidato.


1
RE il primo frammento:This code is not allowed to crash or exit.
Stephen,

Questo non è valido perché esce, il che non è consentito per il primo frammento.
DJMcMayhem


1

Java 8 Cracked di @ OlivierGrégoire

Ho provato a renderlo il più difficile possibile! :) E, a differenza dell'altra risposta Java finora, dovrai seguire le regole esatte della sfida, posizionandola dopo l'intero snippet (quindi no, non inserisci il tuo codice nelpublic static void main(String[] args) metodo, lo metti dopo l'intera lezione. :) Buona fortuna!

Ho aggiunto commenti per mostrare ciò che viene limitato.
( Ispirato da questo post, che è meno restrittivo e percettibile con lo stesso approccio che potrei usare per la mia risposta. )

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

// Your code goes below:

Provalo qui. (ideone.com invece di TIO, poiché non sembra funzionare lì. I test sono stati eseguiti nell'IDE Eclipse, ma la mia soluzione prevista funziona se si utilizza ideone.com)



1

Jelly: CRACKED

Questo sarà follemente facile rispetto alla fantastica risposta Python di Wheat Wizard, ma eccoci qui: P

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø<insert code snippet here>

L'esagoma sha256 della mia soluzione alternativa, incluso il primo frammento, è cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a.

Nota

È possibile che non ci siano nuove righe nel codice tranne che per le stringhe, altrimenti questo codice non verrà nemmeno eseguito, il che vanifica lo scopo di questa sfida.

Craccato da DJMcMayhem

Per essere onesti, questo utilizza una nuova riga, quindi mi piacerebbe vedere una soluzione che non utilizza una nuova riga.

Anche una soluzione di Jonathan Allan

Questo non usa una nuova riga, quindi è stato rotto. : P

La mia soluzione è questa:

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø“print(int(input())+int(input()))”ŒV

Il primo frammento elimina solo gli atomi di singolo carattere, il che significa che Python eval funziona ancora :)))


Il secondo snippet viene sempre aggiunto alla fine del primo snippet.
Stephen,

@StepHen Basta specificare: P Ma ho dimenticato di aggiungere la nota; è davvero importante.
HyperNeutrino,

3
Non penso che tu possa limitare i ladri in quel modo. Se riesci a decifrarlo con Newlines, è una crepa valida. Esiste un modo per impedire l'aggiunta di Newline o forzare l'esecuzione della prima riga?
DJMcMayhem


1
Mi piace il tuo crack voluto. Molto subdolo.
Dennis,

1

JavaScript, incrinato

Ingresso: prompt()due volte

Produzione: console.log()

La mia soluzione non funziona in jsfiddle. Funziona su about: pagina vuota con la console JS di Google chrome.

prompt=console=0

La mia soluzione:

x=document.createElement("iframe")
x.src="data:text/html,<script>console.log(prompt()-0+(prompt()-0))</script>"
document.body.appendChild(x)

Spiegazione:

Ho rimosso prompt e console impostandoli uguali a 0.

Nella mia soluzione creo un iframe, che crea un sandbox e una nuova istanza di finestra in cui prompt e console funzionano correttamente.



@CRDrost Non credo ci siano test di primalità nelle specifiche e tu non mostri entrambi i frammenti.
Stephen,

Scusa, hai ragione, ho letto male.
CR Drost,

1

Java, incrinato

import java.lang.reflect.*;
public class Main{
  public static void main(String... args){
    System.setOut(null);
    System.setErr(null);
    /*Your code here*/
  }
}

Questo dovrebbe essere molto facile da decifrare.

Soluzione prevista

import java.lang.reflect.*;
public class Main{
public static void main(String... args){
  System.setOut(null);
  System.setErr(null);
  try{
    Class<?> cistream = Class.forName("java.io.InputStream");
    Class<?> cfostream = Class.forName("java.io.FileOutputStream");
    Class<?> costream = Class.forName("java.io.OutputStream");
    Class<?> cfdescriptor = Class.forName("java.io.FileDescriptor");
    Object sout = cfostream.getConstructor(cfdescriptor).newInstance(cfdescriptor.getField("out").get(null));
    Class<?> csys = Class.forName("java.lang.System");
    Field mod = Field.class.getDeclaredField("modifiers");
    mod.setAccessible(true);
    Field stdout = csys.getField("out");
    mod.set(stdout,Integer.class.cast(mod.get(stdout) )&~ Modifier.FINAL);
    stdout.set(null,Class.forName("java.io.PrintStream").getConstructor(costream).newInstance(sout));
    Class<?> cscanner = Class.forName("java.util.Scanner");
    Object scanner = cscanner.getConstructor(cistream).newInstance(System.in);
    Method nextInt = cscanner.getMethod("nextInt");
    int f = Integer.class.cast(nextInt.invoke(scanner));
    int s = Integer.class.cast(nextInt.invoke(scanner));
    int sum = s + f;
    System.out.println(sum);
  }catch(Throwable t){t.printStackTrace();}
  }
}

Provalo online



Mi ero completamente dimenticato di java.io.. Ma hai comunque ottenuto la soluzione voluta ...
Roman Gräf,

Non vedo alcun problema qui. In realtà ho scritto il secondo snipet appena dimenticato di modificarlo. Secondo TIO il primo frammento si compila senza alcun preavviso.
Roman Gräf,

@OlivierGrégoire Fatto. Penso che qualsiasi IDE mi urlerà per questo, ma almeno il compilatore lo accetta ...
Roman Gräf,
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.