¡Haga su idioma * mayormente * inutilizable! (Hilo de la policía)


61

Inspirado por este comentario ...

¡Gracias a los usuarios Step Hen , Wheat-Wizard y Dennis por ayudarme a solidificar la especificación de este desafío antes de publicarlo!

Este es el hilo de los policías. Para el hilo de los ladrones, vaya aquí


En este desafío , tiene la tarea de ejecutar un código que haga que su lenguaje ya no satisfaga nuestros criterios de ser un lenguaje de programación. En ese desafío, eso significa hacer que el idioma ya no pueda ...

  • Tomar entrada y salida numérica

  • Suma dos números juntos

  • Prueba si cierto número es primo o no.

Esta es una desafío, donde hay dos retos diferentes con dos objetivos diferentes: los policías se trate de escribir un código que hace que el lenguaje sobre todo inservible, y los ladrones tratarán de encontrar la solución oculto que permite a la policía para recuperar su lenguaje.

Como policía, debes escribir dos fragmentos de código:

  1. Uno que hace que su idioma sea prácticamente inutilizable, por ejemplo, eliminando las funciones integradas para tomar entradas / salidas y operaciones numéricas. Cuantas más funciones elimines, mejor. Este código no puede bloquearse o salir. Debería ser posible agregar código al final de este fragmento, y ese código será evaluado . Y...

  2. ... un fragmento de código que toma dos enteros no negativos como entrada, los agrega y genera su suma. Este fragmento debe funcionar correctamente incluso después de ejecutar el primer fragmento. Cuando los dos fragmentos se combinan, deben formar un programa completo que agregue dos números o definir una función que agregue dos números. Idealmente, este fragmento debe basarse en un comportamiento muy oscuro, para que sea más difícil de encontrar.

Puede elegir cualquier método estándar de entrada y salida . Sin embargo, debe revelar exactamente qué formato (entrada y salida) está utilizando. Un ladrón no puede descifrar su respuesta a menos que use el mismo formato que usted.

Después de escribir estos dos fragmentos, debe publicar el primero como respuesta, sin revelar el segundo. Su respuesta debe contener toda la siguiente información:

  • El primer fragmento (obviamente no el segundo).

  • Idioma (incluida la versión menor, ya que la mayoría de las presentaciones probablemente dependerán de casos extraños)

  • Formato IO, incluso si es una función o un programa completo. Los ladrones deben usar el mismo formato para que su crack sea válido.

  • Cualquier caso extraño requerido para que su respuesta funcione. Por ejemplo, solo se ejecuta en Linux , o requiere una conexión a Internet . Obviamente, esto es un poco subjetivo, pero si un policía tiene un caso extremo que evita que se agriete, y luego solo revela esto después de estar a salvo, considero esta mala deportividad. Un ladrón potencial debe tener toda la información necesaria para descifrar su respuesta antes de descifrarla.

No necesita revelar su recuento de bytes hasta que su respuesta esté segura.

Aquí hay un ejemplo. Para el primer fragmento, puede enviar el siguiente programa Python 3:

Python 3

print=None

Toma entrada de STDIN y salida a STDOUT

Y luego, como tu segundo fragmento, podrías escribir:

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

Esto es válido porque tomará dos números como entrada y generará su suma incluso si une los dos fragmentos, p. Ej.

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

Sin embargo, esto será extremadamente fácil para un ladrón para encontrar una solución. Dado que esto sería muy fácil de descifrar, podría intentar parchear este enfoque particular de esta manera:

import sys
sys.stdout=None
print=None

Sin embargo, incluso esto tiene una solución muy fácil:

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

Como policía, su objetivo es hacer que la solución oculta sea lo más oscura posible, para evitar que los ladrones la encuentren.

Los ladrones mirarán una de sus respuestas e intentarán descifrarla. Pueden descifrarlo escribiendo cualquier fragmento válido que pueda funcionar como fragmento 2 (sumando dos números juntos después de que el idioma quede prácticamente inutilizable). Esto no tiene por qué ser el mismo fragmento que originalmente pretendía. Si un ladrón descifra su respuesta, dejará un comentario en su respuesta, y luego debe editarla para indicar que se ha descifrado. Si su publicación está descifrada, debe editar su respuesta para mostrar la solución (fragmento 2) que pretendía originalmente. Esta no es una regla per se , solo una sugerencia amigable para mantener el juego divertido. Usted no tiene que.

Si una respuesta permanece sin descifrar durante una semana completa, puede editar en su segundo fragmento e indicar que su respuesta ahora es segura . Si no lo edita después de que termine la semana, otros usuarios aún pueden descifrarlo hasta que lo haga. Si no revela su segundo fragmento, no puede reclamar puntos por su respuesta, o llamarlo seguro.

El ganador del hilo de la policía es la respuesta segura más corta que incluye ambos fragmentos , contados en bytes, y esta respuesta será aceptada después de que haya pasado el tiempo suficiente. Usted no tiene que revelar su cuenta de bytes hasta que su respuesta es seguro, ya que cuenta de bytes es irrelevante para su puntuación hasta que su respuesta es seguro. En el caso de que haya pasado suficiente tiempo y no haya respuestas sin descifrar, el ganador será la respuesta que permaneció sin descifrar durante el período de tiempo más largo.

¡Que te diviertas!

Aclaraciones de reglas

  • El primer fragmento debe ejecutarse correctamente sin tomar ninguna entrada . Puede generar lo que desee, y esta salida será ignorada, siempre y cuando el fragmento esté hecho, el segundo fragmento se ejecutará correctamente.

  • El segundo fragmento debe ejecutarse para que su respuesta sea válida. Esto significa una respuesta como

    import sys
    sys.exit()
    

    no es válido porque no rompe el idioma. Simplemente se cierra. Del mismo modo, ingresar un bucle infinito no es válido, ya que el segundo fragmento nunca se ejecutará.

  • Después de estar seguro, su puntaje es el recuento de bytes de ambos fragmentos .

  • Esto se remonta a Por favor, revele los casos extremos extraños necesarios para que su respuesta funcione ... Su envío debe contener suficiente información antes de ser revelado para ser reproducible después de ser revelado. Esto significa que si su respuesta se vuelve segura y luego edita en: Aquí está mi respuesta. Ah, por cierto, esto solo funciona si lo ejecutas en Solaris, ¡es una broma! su respuesta no es válida y se eliminará y no se considerará elegible para ganar.

  • Se permite que el segundo fragmento se bloquee después de generar la suma, siempre y cuando la salida siga siendo correcta (por ejemplo, si elige enviar a STDERR, y luego obtiene un montón de información de bloqueo, esto no es válido).

  • No puede editar su código después de enviar una respuesta.

  • No puede confiar en funciones criptográficas como cifrado, funciones hash, CSPRNG, etc.

Fragmento para encontrar envíos no descifrados:


3
¿Qué se debe hacer para lenguajes como C? La concatenación solo permite un "fragmento principal", y cualquier lógica tendrá que ir allí. Por ejemplo, si tengo a int main(){ do_evil_stuff(); }dónde debe ir el código de usuario? En una función? Después de todas las declaraciones en main?
Conor O'Brien

1
¿Se puede colocar el segundo fragmento en cualquier lugar del primer fragmento?
LegionMammal978

1
No sé nada sobre codificación, pero este desafío se ve increíble,
Pritt Balagopal

2
He editado en fragmento impresionante de jimmy23013 . Siéntase libre de revertir, pero de todos modos lo estaba usando para encontrar envíos y pensé que podría ayudar a otros.
Dom Hastings

2
@DomHastings ¡Eso es extremadamente útil! Muchas gracias :)
DJMcMayhem

Respuestas:


2

Gforth 0.7.3 (TIO) , 231 bytes [SEGURO]

Este código redefine como inútiles algunos métodos de salida necesarios, así como la suma y algo crucial para declarar funciones. ¡Buena suerte!

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

La entrada será dos enteros con signo tomados de la parte superior de la pila como parámetros de función. Salida a STDOUT.

Por lo tanto, debe corregir el daño causado y definir una función que tome los dos valores superiores de la pila e imprima el resultado como un entero (no un flotante) en STDOUT sin salida adicional (sin espacio final).

Aquí hay una plantilla , si se nombra su función objetivo f.

Solución:



En realidad, 79 bytes eliminé la immediatepalabra clave del final de la redefinición ;, por lo que era necesario que una respuesta la incluyera al principio. La función que definí es en su mayoría equivalente a la definición interna de ., pero no imprime el espacio al final, y la suma se realiza primero, moviendo los números a la pila de coma flotante y viceversa.

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

Pruébalo en línea


1
Esta es una muy buena respuesta. ¡A este ritmo, parece que podría terminar siendo la única respuesta sin descifrar!
DJMcMayhem

:) Combiné un par de obstáculos diferentes. En este punto, me pregunto si podría haber hecho solo uno para mejorar mi puntaje. Pero es posible que tener más de uno sea la razón por la que aún no se ha descifrado.
mbomb007

21

Haskell, agrietado por Christian Sievers

import Prelude(getLine,print)
a=a

Programa completo, lectura de dos enteros (incluidos los negativos) desde stdin y escritura en stdout.

Acabo de deshabilitar el Preludio para que casi nada esté dentro del alcance, y luego agregué una definición; otras importaciones son sintácticamente inválidas. Te di getLiney printsin embargo.


Editado para agregar mi solución original. El crack de Christian fue diferente, pero explota las mismas características básicas (puede obtener una cantidad sorprendente de cómputo al acceder a funciones que tienen azúcar sintáctico, incluso cuando no puede llamar a nada directamente o incluso nombrar los tipos involucrados).

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

Lo que probablemente no sea súper golf de todos modos, pero aquí es más fácil de leer:

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 , agrietado

Implementa la adición como una función con nombre

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\

Pruébalo en línea!

¿Qué hace esto?

Con el fin de ayudarte un poco, explicaré lo que hace. Este código abre el archivo fuente y comprueba si el resto del código cumple los siguientes criterios:

  • No contiene la cadena import
  • Está hecho únicamente de los personajes. &)(,.:[]a`cdfijmonrt~

Si falla cualquiera de los criterios, el límite de recursión se establece para 1que cualquier código que escriba llegue al límite de recursión.

Aquí no hay trucos, he escrito una solución que usa solo estos caracteres y no importa, no estoy haciendo nada subversivo, pero diré que creo que será bastante difícil de descifrar.

Para ahorrarle tiempo, aquí hay una breve lista de cosas útiles que no puede hacer con esta restricción

  • + bueno duh

  • eval/ execNo iba a dejarte escapar con eso

  • Números, pueden ser más útiles de lo que piensas

  • Literales de cadena

  • len

  • =, Sin asignación de variables

  • >, <, ==. . . Te he dejado sin comparaciones

  • *, -, /, %, ^, |, >>, << Los únicos operadores disponibles son ~y&

  • __foo__, Ninguno de esos elegantes métodos de doble subrayado están permitidos.


1
Wow, esto es bastante malvado. ¡Agradable!
HyperNeutrino

Fantástica respuesta para comenzar :)
DJMcMayhem

Jeje, esto podría haber sido inspirado por el tonto desafío del rey de la colina que intenté especificar en el chat esa vez
Stephen

44
Creo que este es un crack válido: codegolf.stackexchange.com/a/133209/68942
HyperNeutrino

RE el primer fragmento: This code is not allowed to crash or exit.(vea el chat para discutirlo)
Stephen

12

Python 2 , agrietado

Esta es la cuarta iteración de esta respuesta. Cada una de las últimas respuestas se descifró al restablecer la profundidad de recursión.

Implementa la adición como una función con nombre

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\

Pruébalo en línea!

¿Qué hace esto?

Con el fin de ayudarte un poco, explicaré lo que hace. Este código abre el archivo fuente y comprueba si el resto del código está compuesto únicamente por los caracteres. &)(,.:[]a`cdfijmonrt~

Si falla, el límite de recursión se establece para 1que cualquier código que escriba llegue al límite de recursión.

También he desactivado todos los módulos, por lo que no puede importar nada.

Aquí no hay trucos, he escrito una solución que usa solo estos caracteres y no importa, no estoy haciendo nada subversivo, pero diré que creo que será bastante difícil de descifrar.

Para ahorrarle tiempo, aquí hay una breve lista de cosas útiles que no puede hacer con esta restricción

  • + bueno duh

  • eval/ execNo iba a dejarte escapar con eso

  • Números, pueden ser más útiles de lo que piensas

  • Literales de cadena

  • len

  • =, Sin asignación de variables

  • >, <, ==. . . Te he dejado sin comparaciones

  • *, -, /, %, ^, |, >>, << Los únicos operadores disponibles son ~y&

  • __foo__, Ninguno de esos elegantes métodos de doble subrayado están permitidos.

Mi solución

Así que ahora que xnor lo ha resuelto de una manera con la que estoy suficientemente satisfecho, voy a revelar mi solución

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, es una enorme pila de galimatías. En lugar de desglosar esto, voy a pasar por el proceso de cómo hice esto.

Empecé con un algoritmo de suma bastante estándar

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

Luego utiliza un truco bit a bit para representar ^con |, &, ~.

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

Usé otro truco bit a bit para deshacerme del |

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

Ahora todo lo que queda es el <<, no debería ser demasiado difícil, ¿verdad? Bueno, prepárate para un viaje lleno de baches. Para reemplazar el desplazamiento de bits, utilicé cadenas para agregar un cero al final de su representación binaria

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

Esto tiene algunos problemas, pero el principal está usando la suma , así que trabajé alrededor de esto usando un formato en su lugar

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

No se nos permite usar bin, así que usé el formato de cadena para convertir a binario.

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

Dado que los literales de cadena están prohibidos, tengo que construir la cadena a {0:b}0partir de partes hechas con ticks posteriores y joinjuntas.

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

La cadena vacía es bastante fácil, solo puedes hacer

`r`[:0]

Los ceros eran

`0`

y {:}todos fueron tomados de los diccionarios.

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

bparece bastante difícil de conseguir, no es en nuestro conjunto de caracteres, así que ¿cómo se supone que vamos a obtener un objeto que tiene una ben su repr? Bueno, aquí está cómo: cuando usa repruna función incorporada, obtiene algo que se parece a

<built-in function name>

Y eso es de donde obtendremos nuestro 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

Ahora todo lo que queda son números, solo necesito -1, 0, 1 y 2, así que así es como los representé:

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

2 en realidad podría ser un byte más corto como

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

basado en las sugerencias de @ Blender en los comentarios, pero no pensé en esto hasta después del hecho.

Entonces sustituimos estos números en

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

Y esa es la grieta.


Este fragmento parece ser un error por sí solo.
ATaco

@ATaco Creo que esto se discutió en el chat y se decidió que estaba bien.
Wheat Wizard

Las reglas establecen explícitamente lo contrario. "No se permite que este código se bloquee o salga".
ATaco

@ATaco Aquí está el mensaje que dijo que lo actualizaría cuando tuviera la oportunidad.
Wheat Wizard


10

C (gcc) ¡Agrietado!

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

Pruébalo en línea!

Entrada de STDIN y salida a STDOUT.

Esto se ejecuta sin error. Jajaja esto es bastante malvado. Solo lo probé en el gcc de TIO. Como de costumbre, debe agregar su código después de este fragmento para que funcione :) El comentario es malo, no lo escuche.

Probado en gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1). Debería funcionar en cualquier sistema Linux.

Solución original

#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
¡Especifica tu plataforma!
Joshua

@Joshua He agregado información
Conor O'Brien


Bueno, __asm__y tienes muchas funciones para elegir :) no pienses que C y C ++ son buenos enemigos aquí.
edmz

10

C (GCC en Linux) (agrietado)

En lugar de utilizar técnicas tontas de sandboxing de lectura de archivos, lo hacemos de la manera correcta, ¡con la lista blanca SECCOMP!

Su tarea: implementar la suma con entrada de STDIN y salida 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!
}

Pruébalo en línea!

¿¡Que es esto!?

Para ayudarlo en su tarea insuperable, explicaré lo que hace este código.

__attribute__ ((constructor(0)))asegura que la sfunción se ejecute primero. La función cierra todos los descriptores de archivos abiertos para STDIN, STDOUT y STDERR. Luego, el programa se limita a sí mismo con una estricta lista blanca SECCOMP, que limita las llamadas de su sistema a lo siguiente:

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

Por lo tanto, no puede abrir ningún archivo nuevo (o básicamente hacer algo). Luego pasamos a main y llamamos a su código, bien envuelto en la sandboxfunción.

Al syscall(SYS_exit, EXIT_SUCCESS);final es solo para garantizar que el programa salga limpiamente; de ​​manera predeterminada, GCC saldrá con lo exit_group(2)que no está permitido por la lista blanca SECCOMP. Esta función existente se llama después de ejecutar su código.

Por lo tanto, no tiene descriptores de archivo abiertos y no puede abrir nada nuevo. Imposible, ¿verdad? ;)



9

Haskell , agrietado por Ben

main=main--

Pruébalo en línea! Este debería ser un programa completo que lea dos números de stdin y envíe la suma a stdout.

Cada programa completo comienza ejecutando la mainfunción, pero aquí se mainllama a sí mismo y provoca un bucle infinito. Para empeorar las cosas, se inicia un comentario de línea --directamente detrás de la llamada recursiva para evitar cambiarlo a, por ejemplo, main2y luego definir eso para hacer la suma.


Solución prevista:

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

Pruébalo en línea!

--comienza un comentario de línea a menos que también se pueda analizar como parte de un operador. (El resaltado de sintaxis parece ignorar este hecho.) --$Es un operador infijo válido que toma maincomo primer argumento y algún segundo argumento ficticio (). Luego se define para ignorar ambos argumentos y realizar la tarea requerida.


2
Ben

55
simplemente puede agregar "where main = ..."
michi7x7

+1 para una solución de Haskell que solo funciona debido a la evaluación perezosa de Haskell.
Julio

8

Montaje en modo real x86 de 16 bits ( agrietado )

_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

Fácil si sabes el truco.


1
¿Cómo estás tomando la entrada? ¿En la pila o en registros? (Además, parece que esto se supone que es el montaje de 16 bits, pero si es así, or [bp], 256. No es válido es que supone que es or WORD PTR [bp], 256?)
Cody Gris

1
Además, debe especificar qué procesador está utilizando; Hay muchas versiones x86 y clones, y muchas instrucciones indefinidas. Si escribiera código para una "oscura 80186 clon" que tan pasó a tener una instrucción indefinida que dio unos argumentos y bla, bla, bla ... También puede ser que necesite el medio ambiente. Windows de 16 bits dio una garantía SS == DS que otros sistemas podrían no tener, por ejemplo.
Orion

1
Solo necesita especificar qué procesador si realmente está utilizando algún truco que funciona solo en un modelo en particular (o una generación en particular). Este código no es así, así que creo que "x86-16" es suficiente. En mi opinión, cuanto más general, mejor. Convino en que debería especificarse el modo real o protegido, aunque la presencia de la hltinstrucción (anillo 0) implica que este no es un modo protegido.
Cody Gray

3
@Joshua si no funciona en todas las plataformas, creo que al menos debe especificar una plataforma en la que funcionará. Your submission must contain enough information before being revealed to be reproducible after being revealed
Stephen

1
@StepHen: la solución para descifrar el lenguaje es independiente de la plataforma una vez especificado el modo real x86-16, pero la E / S no es independiente de la plataforma. El que lo explota puede especificar el sistema operativo para el que se rompió. Agregué la etiqueta _main tarde para que, en teoría, alguien pudiera hacer una pausa casi agnóstica al unirse contra libc.
Joshua

4

Javascript, agrietado

Este desafío se basa en el de Grant Davis , pero soluciona la solución que tenía en mente (que crea un iframe y usa el iframe window). La solución se ejecuta en la consola de JavaScript en Chrome about:blank page, y toma dos input()segundos, los agrega y da console.logel resultado. Pon tu código después de:

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

En primer lugar, nos daban un golpe prompty consoley establecer el acceso directo d. Luego, creamos un observador de mutaciones con una devolución de llamada que elimina cada objetivo mutado. Configuramos ese observador de mutaciones para observar el documento y notificarlo childListy realizar subtreemodificaciones. En lugar del literal true, usamos nuestro acceso directo al valor verdadero document(la especificación no permite esto, pero Chrome sí).

Después de publicar esto, me di cuenta de un golpeador mucho más elegante. Mi solución prevista todavía funciona, pero el crack publicado no:

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

Bienvenido al sitio! Estoy interesado en ver cuál será la solución :)
DJMcMayhem


4

Perl 5, agrietado por 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__

La entrada se recibe en líneas separadas STDINy la salida se imprime en STDOUT.

Todo el código va después del __DATA__marcador. Esto utiliza un método similar a la solución de @ WheatWizard en que el código se analiza y se eliminan los caracteres inutilizables.

Esto se ha probado en las versiones 5.8, 5.10 y 5.16, y no requiere indicadores de línea de comandos.

Pruébalo en línea!


2
¿Podría especificar el método y el formato de entrada / salida?
Ilmari Karonen

@IlmariKaronen Disculpas, es STDINcon caracteres en líneas separadas y STDOUT. Agregaré esto al cuerpo principal.
Dom Hastings


4

Python 3, agrietado por zbw

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

Se han eliminado todos los modlues, lo que significa que no hay builtins disponibles y no se puede hacer mucho más. Salida a STDOUT, entrada de STDIN. Esta es la segunda iteración de esta respuesta después de que la anterior se rompió por una grieta trivial al agregar una declaración de interrupción.


Tengo mucha curiosidad por ver el fragmento que funciona después de esto
NickA

Bueno, tienes que esperar siete días o una grieta no trivial, lo que ocurra primero ...
pppery


Bueno, bueno, desafíos como estos son muy difíciles de hacer bien
pppery

4

APL (ngn-apl) , agrietado por ngn

Hecho en cooperación con mi colega Marshall .

Entrada a través de argumentos izquierdo y derecho para +. Es decir, su objetivo es insertar código después de lo siguiente, para que su última línea lea ⎕←3+2y salga 5a STDOUT.

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

Pruébalo en línea!

Funciona configurando todas las funciones útiles para las {}cuales toma uno o dos argumentos y devuelve una lista numérica vacía. También se configura para componer funciones.


Grieta

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

⍺⍵1/0 replicar 0 por el argumento izquierdo y el argumento derecho y 1

 obtener los índices que ordenarían eso (dado que todos los elementos son cero, da 0 1 2 ... (a + b)

⌈/ el valor máximo (a + b)


ngn / apl incluye la capacidad de ejecutar JavaScript arbitrario. No considero que tal solución sea válida, ya que se trataría de deshabilitar JavaScript en lugar de APL. De hecho, hay una forma válida (aunque oscura) de restablecer +usando solo APL puro y sin trucos sucios.
Adám

3

Python 2 , agrietado

Esta es la segunda iteración de una respuesta que ha sido descifrada una vez por @HyperNuetrino usando un método que no esperaba. Ahora lo he parchado, así que espero que las únicas soluciones que quedan tengan que cumplir con las restricciones que pretendía.

Implementa la adición como una función con nombre

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\

Pruébalo en línea!


Creo que podría hacer esto si tuviera un u, pero estoy atrapado sin él.
isaacg

@isaacg Solo por curiosidad, ¿con qué te gustaría u?
Wheat Wizard

.count. Puedo obtener una cadena tan larga como la salida deseada, pero no tengo forma de tomar su longitud.
isaacg

__import__('sys').setrecursionlimit(100)... y nada fue reparado. Sin embargo, no tengo ganas de publicarlo en el hilo del ladrón, se siente como hacer trampa. Pruébelo en línea
Value Ink


3

Java 8, crackeado por @ OlivierGrégoire

Aquí está mi intento. Más o menos, la idea es sobrecargar todos los espacios de nombres que puede usar para generar (y reflexionar, espero). La salida está destinada 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{}
}

Las listas negras suelen ser un enfoque peor que las listas blancas, por lo que estoy seguro de que es solo cuestión de tiempo antes de que alguien presente un enfoque que no consideré.


1
Esta no es una clase ejecutable ...
Olivier Grégoire

1
@ OlivierGrégoire Lo siento, agregué class String{}después de probar sin darme cuenta de que noquearía main(String[] ...). Debería funcionar ahora
Lord Farquaad

1
Sí, eso lo hará, ¡gracias! :) Sin embargo, no cambia la grieta que estoy a punto de hacer: p
Olivier Grégoire

1
¡Agrietado! Realmente disfruté este :)
Olivier Grégoire

1
Estaba mirando algo como esto (lo siento, es difícil formatear el código en los comentarios), pero creo que su solución es mucho más limpia: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, resquebrajados por Mayube

#|1,1:A

Esto debería ser bastante fácil, pero nunca se sabe.

El "problema" fue que sin Csu código, recibió un error.

La solución de Mayube:

#|1,1:A+BC

Cada elemento de la secuencia es la primera entrada más la segunda por la tercera (también conocido como 1)

Mis soluciones:

#1,1:A+B,C

La secuencia cambia entre la primera entrada más la segunda entrada y la tercera entrada (1). El primer elemento en el segundo es A+B.

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

Similar a la solución de Mayube: en lugar de multiplicar B*C, solo suma Cy luego resta.

Pruébalo en línea!

Explicación

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

Actualmente, este programa genera 1, ya que sin entrada del usuario, la primera entrada es la primera 1en la entrada predeterminada ( #).


Los documentos parecen estar redactados de manera extraña, no puedo por mi vida entender qué significa cuando 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 es raro, necesito encontrar una manera de decirlo correctamente. Básicamente, su entrada al programa puede ser igual a la entrada más alta consultada por las variables A,B,C,D,Een el código. Por ejemplo, si en algún momento tiene la variable Den su programa, el analizador espera que haya 4 entradas, pero si también hay una E, el analizador espera que haya 5 entradas. No puede haber menos de la cantidad esperada. Sin embargo, siempre hay una última entrada opcional n, que se utiliza de diferentes maneras por diferentes modos.
Stephen

@Mayube el fragmento que publiqué arriba contiene un A, por lo que busca una entrada. Dado que hay dos, ambas procedentes de las #cuales especifica la entrada predeterminada, utiliza la primera como Avalor y la segunda como n.
Stephen

Entonces, si tuviera que dar 2 entradas y agregar BC, ¿A sería la primera entrada, B sería la segunda, C sería 1 y n sería la segunda 1?
Skidsdev

@Mayube exactamente, lo siento por mis documentos de mierda. TMI: si el comienzo se viera como #1,1(sin barra), sería: A como el primer 1, B como el segundo 1, C como la primera entrada yn como la segunda entrada. También puede hacerlo #1|1, donde A es el primer 1, B es la primera entrada, C es la segunda entrada yn es el segundo 1.
Stephen

3

Node.JS versión 7.3.0 (descifrado por 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)})();

Coloque el segundo bloque de código después del primero.

Descargo de responsabilidad: el segundo bloque de código no funcionará solo (sin colocarse después del primero). Sin embargo, si esto no está permitido, puedo modificar el segundo fragmento.

Este es un programa completo. La salida es process.stdout(STDOUT), la entrada es process.argv(argumentos de línea de comando)

Estos son mis primeros policías y ladrones, espero que este sea un buen desafío :)

Pruébalo en línea!


El desafío explicado

Genera una variable aleatoria nde 0 a 1e7. Si llama a escribir con el correcto n, no imprime nada pero se establece len 0, lo que "desbloquea" la función de escritura, lo que le permite imprimir cualquier cosa. Si intenta llamar a escribir con una no cadena, lo envía a un bucle infinito. Si intenta llamar a escribir con otra cosa que no sea la correcta nmientras la escritura está "bloqueada", lo envía a un bucle infinito para evitar que adivine.

La solución prevista

Se escabulle más allá del tipo que aparentemente busca cadenas solo mediante el uso de un Símbolo, que también comienza con s. Esto arroja un error en la función resultante de la llamada eval porque no puede agregar la cadena "f" a un Símbolo. Detectamos el error y usamos regex para recuperar nel seguimiento de la pila, donde está en el nombre de la función. Luego intentamos escribir nlo que no imprime nada, pero establece la variable "bloquear" len 0 para "desbloquear" la función de escritura. Ahora que la función de escritura está desbloqueada, solo imprimimos la suma.

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


Eso es genial ... ¡Estaba en el camino correcto originalmente entonces! Gracias por el entrenamiento cerebral!
Dom Hastings

3

RProgN2 , agrietado por Arnold Palmer

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

Escribe sobre todos los operadores matemáticos, sin forma de restaurarlos. En particular, los reemplaza con una función que elimina los dos elementos superiores de la pila.

Pruébalo en línea!

Solución original

{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.

Pruébalo en línea!


Estoy revisando su documentación y parece que no puedo encontrar lo que hace el ²símbolo. ¿Te importaría iluminarme?
Arnold Palmer

Esa documentación no es increíblemente relevante para RProgN2, y ese símbolo toma los siguientes dos conceptos [[en este caso, y los envuelve en una función @ArnoldPalmer
ATaco


Dang, eso está mucho mejor. No sabía acerca de los operadores de pila, lo que seguramente habría sido útil. Además, conocer «»crea variables locales en lugar de estropear las globales habría sido de gran ayuda.
Arnold Palmer

3

Haskell, 161 144 bytes, agrietado por BlackCap

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

Entrada a STDIN, salida a STDERR. Añadir al final del programa.

Editar: destinado a ser compilado sin argumentos adicionales de GHC, solo lo normal ghc --make prog.hs.

Editado nuevamente para reducir el recuento de bytes.

¡Que te diviertas!


¿Entonces no puedo hacer esto porque no se llamará a la función principal? main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap

@BlackCap No, porque GHC espera que la mainfunción esté en el módulo Maincuando no -main-isse proporciona ninguna marca .
zbw

Esto no funciona, pero quiero compartir la idea de todos modos
BlackCap

Llamaré a eso agrietado. Aquí estaba mi solución prevista, jugar golf. No funciona en TIO, porque el contenedor no envía la entrada al compilador.
zbw

Si publica su solución, la marcaré como agrietada.
zbw

3

Mascarpone , agrietado por 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<^$

La entrada es números de iglesia en stdio, usando ipara incremento y zpara cero. Por ejemplo, 2 + 3 sería:

iiziiiz

Con una nueva línea final, la

salida debe ser un número en stdout, en el mismo formato que en stdio. Por ejemplo, si la respuesta es cinco, debe generar:

iiiiiz

(Mascarpone no tiene concepto de números)


Solución prevista:

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

No es inmediatamente aparente a partir de la documentación, pero como dijo @IlmariKaronen en su crack, los literales de cadena en Mascarpone son en realidad azúcar sintáctica para empujar una secuencia de caracteres.

Deliberadamente escribí comentarios como [this]$para hacer que parezca que estoy presionando una cuerda y haciendo estallar inmediatamente después. Un ingenuo cracker podría haber intentado algo como [:,>!]/*empujar una cadena, intercambiarla con el intérprete e interpretarla.

También pretendo mostrar el intérprete que dejé en la pila $, pero $ya se ha redefinido a un NOP. Te queda este intérprete en la pila, y tienes que llevarlo contigo durante todo el programa; a través de cada carácter de cada cadena.


Agrietado. Y no, nunca había oído hablar de Mascarpone antes de este desafío.
Ilmari Karonen

@IlmariKaronen ¿Nuevo idioma favorito? ¡Buen trabajo!
BlackCap

2

C # (.NET Core) agrietado por Ilmari Karonen

También agrietado por Joshua .

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

Lee los dos valores de stdin y escribe el resultado en stdout. Probado en Windows con Framework Versión 3, 4.6 y en TIO .

Aquí está el programa completo que tenía la intención.

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

Pruébalo en línea!



codegolf.stackexchange.com/a/133412/14306 Supongo que esta no era la solución prevista.
Joshua

@IlmariKaronen: +1. Esta fue la solución prevista.
raznagul

@Joshua: +1 por encontrar una solución diferente de la que pretendía.
raznagul

2

GolfScript , descifrado por Dennis

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

Pruébalo en línea!

Este es un desafío de , después de todo, entonces, ¿por qué no probar GolfScript?

Una solución válida debe ser un fragmento que lea dos enteros de la pila, los sume y devuelva el resultado en la pila. El problema es que aún debería funcionar incluso después de que el código anterior haya redefinido casi todos los operadores de GolfScript integrados para no hacer absolutamente nada. Al menos lo dejé ;intacto, por lo que aún puede extraer valores de la pila. ;-) Su código debería funcionar en el intérprete estándar de GolfScript, tal como se implementa, por ejemplo, en TIO (consulte el enlace anterior).


La solución de Dennis , como la mía , se basa en la característica poco utilizada de GolfScript que permite el código Ruby interpolado en cadenas de comillas dobles. Usamos esta función para definir un nuevo operador de suma que funciona exactamente como el +operador incorporado y luego lo llamamos.

(Una razón por la cual la característica de interpolación Ruby en GolfScript se usa tan raramente es que, incómodamente, el código Ruby interpolado se ejecuta durante el análisis y el intérprete GolfScript almacena en caché su salida. Por lo tanto, si tiene una cadena con código Ruby interpolado en un bucle, el código se ejecutará solo una vez antes de que comience el programa real y, a partir de entonces, siempre devolverá el mismo valor en cada iteración del bucle. Puede solucionarlo utilizando la evaluación de cadena para diferir el análisis, pero eso hace que la sintaxis ya sea aún más incómoda feo y detallado, y en cualquier caso, para este desafío también deshabilité el operador eval ~. Sin embargo, resulta que definir nuevos operadores GolfScript incorporados es una cosa que esta característica realmente hace bastante bien y limpiamente).



Agrietado. Finalmente descubrí lo que estaba haciendo mal.
Dennis

@ Dennis: Sí, esta vez lo lograste. FWIW, mi solución prevista era "#{var'_','gpush a+b'.cc2}";_, que funciona exactamente como la suya, excepto por ser unos pocos bytes más cortos.
Ilmari Karonen

2

Node.js v8.2.0, descifrado por 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) )
                 );
}

Debes implementar la logicfunción. La entrada son los argumentos proporcionados (desde stdin), la salida es lo que devuelve su función (se imprime en stdout).


Mi código de iglesia codifica los números de la entrada. El resto del código está ahí para intimidarte.
La función de desorden hace algunos trucos para implementar la notación sin puntos ( a . b == dot (a) (b)), que uso principalmente para agregar . id .a lugares aleatorios, que no hace nada, pero confundirá a cualquiera que no esté familiarizado con la programación funcional.
La transformación aplicada a los números antes de pasarlos a la logicfunción es x+1y y-1, que suma hasta 0, por lo que es otro NOP para agregar a la oscuridad.

La solución prevista fue:

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


@DomHastings Esa no es la solución prevista, pero voy a decir que puede hacerlo, siempre que el programa se detenga sin excepción y no imprima caracteres adicionales en la salida
BlackCap

¡Acabo de publicar una alternativa! (¡Puedes ver mi solución anterior en la historia de esa respuesta!)
Dom Hastings

Oh wow, estaba muy lejos ... ¡Aún así es mejor que mi primer intento muy engañoso! Gracias por el rompecabezas!
Dom Hastings

2

Informar 7 , agrietado por ppperry

For reading a command: rule fails.

[Your code here.]

El jugador debe escribir la entrada como un comando interactivo, por ejemplo, add 17 to 25o sum 17 25. Usted es libre de elegir la forma exacta del comando que debe ingresarse, siempre que incluya dos números. La suma de los números (p 42. Ej. ) Debe imprimirse en respuesta al comando.

El desafío, por supuesto, es hacerlo mientras toda la actividad de "leer un comando" se reemplaza por un no-op. Probablemente hay varias formas de resolver este problema, pero al menos debería requerir cierta familiaridad con el lenguaje. El que se me ocurrió es bastante simple, aunque un poco inesperado.

He probado mi solución en el GNOME Inform 7 IDE, versión 6L38 , en Ubuntu Linux. La solución prevista funciona tanto en el back-end de Glulx como en la máquina Z, y también debería funcionar en otras versiones recientes de Inform 7. Tenga en cuenta que (sin una solución alternativa adecuada) el código anterior hará que el intérprete trabaje en bucle cuando intente leer un comando; el intérprete de la máquina Z parece dejar de responder por completo cuando esto sucede, y no se puede detener desde el IDE, por lo que recomiendo usar Glulx para las pruebas.


agrietado , y en caso de que te lo estés preguntando, nunca había oído hablar antes de este desafío
pppery

2

CPython 3 (nuevamente), agrietado por Sísifo

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

Puede hacer lo que quiera, siempre y cuando no esté implementado en C. Esto significa que no print, no input, todos ellos llegarán a la _(1)línea y terminarán. Entrada de STDIN con los números en dos líneas separadas, salida a STDOUT. Me pregunto cuánto tiempo va a durar esto ... Me llevó bastante tiempo encontrar el segundo fragmento de trabajo después de encontrar este truco de discapacidad. Especificar explícitamente Cpython para evitar ser descifrado basado en alguna implementación alternativa de sys.setprofile.


Agrietado. Tengo muy poca idea de por qué esto funciona.
Sísifo

Creo que puedo preguntar ahora: ¿por qué functools?
Dennis

@Dennis Porque Sispyphus descubrió una escapatoria, no la solución prevista
pppery

@Sisyphus Tu crack ha sido reportado como un error en python
pppery

2

Java 8 ( agrietado )

Segundo intento. Esta vez invertí dos minutos de prueba.

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 mayoría de las cosas deberían estar cubiertas.


1
¿Podría incluir esto en una clase con las importaciones apropiadas? Es el tipo de desafío donde estos pequeños cambios pueden hacer o deshacer una entrada. Obtuve varias soluciones para esta como es, pero eso se reduce drásticamente si simplemente lo incluye en una clase / interfaz. Además, el formato para eliminar todas esas líneas mientras que sería bastante agradable para nosotros, lectores.
Olivier Grégoire

Allí, una respuesta descifrada usando exactamente su código. Y un +1 porque parece que lo olvidé. Lo siento.
Olivier Grégoire

Las llamadas #setAccessible (false) no hacen nada.
Nevay

1

Python 2 agrietado

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

Pruébalo en línea!

Prefiero esto diciendo que esta respuesta es un movimiento brusco, pensado como una respuesta de límite inferior.


Inspirado por las respuestas de Wheat Wizard e HyperNeutrino .

El fragmento lee el archivo fuente y se niega a continuar si el último fragmento de código separado por espacios en blanco no aparece e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843.

EDITAR : Editado ligeramente en respuesta a este comentario . El problema central no cambia, no se invalida ningún intento de crack.


1
RE el primer fragmento:This code is not allowed to crash or exit.
Stephen

Esto no es válido porque se cierra, lo que no está permitido para el primer fragmento.
DJMcMayhem


1

Java 8 Craqueado por @ OlivierGrégoire

Traté de hacerlo lo más difícil posible! :) Y, a diferencia de la otra respuesta de Java hasta ahora, tendrás que seguir las reglas exactas del desafío, colocándola después de todo este fragmento (así que no, no pones tu código en el public static void main(String[] args)método, lo pones después de toda la clase. :) ¡Buena suerte!

He agregado comentarios para mostrar lo que se está restringiendo.
( Inspirado en esta publicación, que es menos restrictiva y tolerable con el mismo enfoque que podría usar para mi respuesta ) .

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:

Pruébalo aquí. (ideone.com en lugar de TIO, ya que no parece funcionar allí. Se han realizado pruebas en el IDE de Eclipse, pero mi solución prevista funciona si usa ideone.com)



1

Gelatina: Agrietada

Esto será increíblemente fácil en comparación con la increíble respuesta de Python de Wheat Wizard, pero aquí vamos: P

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

El sha256 hexdigest de mi solución alternativa, incluido el primer fragmento, es cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a.

Nota

Es posible que no tenga ninguna línea nueva en el código, excepto las cadenas; de lo contrario, este código ni siquiera se ejecutará, lo que anula el propósito de este desafío.

Agrietado por DJMcMayhem

Para ser justos, esto usa una nueva línea, por lo que me gustaría ver una solución que no use una nueva línea.

También una solución de Jonathan Allan

Esto no usa una nueva línea, por lo que ha sido descifrado. :PAGS

Mi solución es esta:

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

El primer fragmento solo elimina átomos de un solo carácter, lo que significa que Python eval todavía funciona :)))


El segundo fragmento siempre se agrega al final del primer fragmento.
Stephen

@StepHen Solo especificando: P Pero olvidé agregar la nota; Eso es realmente importante.
HyperNeutrino

3
No creo que puedas restringir a los ladrones así. Si puedes descifrarlo con Newlines, es un crack válido. ¿Hay alguna forma de evitar que se agreguen nuevas líneas o forzar la ejecución de la primera línea?
DJMcMayhem


1
Me gusta tu crack previsto. Muy astuto
Dennis

1

JavaScript, agrietado

Entrada: prompt()dos veces

Salida: console.log()

Mi solución no funciona en jsfiddle. Funciona en la página acerca de: en blanco con la consola JS de Google Chrome.

prompt=console=0

Mi solución:

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

Explicación:

Eliminé prompt y console configurándolos igual a 0.

En mi solución, creo un iframe, que crea un sandbox, y una nueva instancia de ventana donde prompt y console funcionan correctamente.



@CRDrost No creo que haya una prueba de primalidad en la especificación, y no muestra ambos fragmentos.
Stephen

Lo siento, tienes razón, leí mal.
CR Drost

1

Java, agrietado

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

Esto debería ser muy fácil de descifrar.

Solución 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();}
  }
}

Pruébalo en línea



Me olvidé por completo java.io... Pero de todos modos obtuviste la solución deseada ...
Roman Gräf

No veo ningún problema aquí. De hecho, escribí el segundo fragmento, solo olvidé editarlo. Según TIO, el primer fragmento se compila sin previo aviso.
Roman Gräf

@ OlivierGrégoire Hecho. Creo que cualquier IDE me gritará por esto, pero al menos el compilador lo acepta ...
Roman Gräf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.