Duas saídas

17

O desafio

Apresento a vocês outro desafio de espião contra espião, colocando ofuscadores versus crackers. Nesse caso, no entanto, o dado a ser protegido não é uma entrada, mas uma saída .

As regras do desafio são simples. Escreva uma rotina com as seguintes especificações:

  1. A rotina pode ser escrita em qualquer idioma, mas não pode exceder 320 bytes.
  2. A rotina deve aceitar três números inteiros assinados de 32 bits como entradas. Pode assumir a forma de uma função que aceita 3 argumentos, uma função que aceita uma única matriz de 3 elementos ou um programa completo que lê 3 números inteiros de qualquer entrada padrão.
  3. A rotina deve gerar um número inteiro de 32 bits assinado.
  4. Sobre todas as entradas possíveis, a rotina deve gerar entre 2 e 1000 valores exclusivos (inclusive). O número de valores exclusivos que uma rotina pode gerar é chamado de chave .

Como exemplo, o programa C

int foo( int i1, int i2, int i3 ) {
    return 20 + (i1^i2^i3) %5;
}

tem uma chave de 9, desde que (espera-se) só pode produzir os valores nove 16, 17, 18, 19, 20, 21, 22, 23, e 24.

Algumas limitações adicionais são as seguintes:

  1. A rotina deve ser totalmente determinística e invariável no tempo, retornando saídas idênticas para entradas idênticas. A rotina não deve fazer chamadas para geradores de números pseudoaleatórios.
  2. A rotina pode não depender de "variáveis ​​ocultas", como dados em arquivos, variáveis ​​do sistema ou recursos de linguagem esotérica. Por exemplo, as rotinas geralmente não devem se referir a constantes, a menos que as constantes estejam claramente definidas no próprio código. Rotinas que dependem de peculiaridades do compilador, saídas de operações matematicamente indefinidas, erros aritméticos etc. também são fortemente desencorajadas. Em caso de dúvida, pergunte.
  3. Você (o codificador) deve saber exatamente quantas saídas exclusivas a rotina pode produzir e deve poder fornecer pelo menos uma sequência de entrada que produza cada saída. (Como pode haver centenas de saídas exclusivas, esse conjunto só seria solicitado no caso de sua chave ser contestada.)

Como esse problema apresenta muito menos semelhança com a criptografia clássica do que a anterior, espero que seja acessível a um público mais amplo.

Quanto mais criativo melhor.

A pontuação

O menor número de envios sem rachaduras por contagem de bytes será declarado o (s) vencedor (es).

Se houver alguma confusão, não hesite em perguntar ou comentar.

O Contra-Desafio

Todos os leitores, incluindo aqueles que enviaram suas próprias rotinas, são incentivados a "quebrar" as submissões. Um envio é quebrado quando sua chave é postada na seção de comentários associados. Se uma inscrição persistir por 72 horas sem ser modificada ou quebrada, ela será considerada "segura" e qualquer sucesso subsequente na quebra será ignorada por causa do concurso.

Apenas uma tentativa de quebra por submissão por leitor é permitida. Por exemplo, se eu enviar ao usuário X: "sua chave é 20" e eu estiver errado, o usuário X rejeitará meu palpite como incorreto e não poderei mais enviar sugestões adicionais para esse envio.

Os envios rachados são eliminados da disputa (desde que não sejam "seguros"). Eles não devem ser editados. Se um leitor deseja enviar uma nova rotina, deve fazê-lo em uma resposta separada.

A pontuação de um cracker é o número de envios (compatíveis ou não) que ele obtém. Para crackers com contagens idênticas, a classificação é determinada pela contagem total de bytes em todos os envios quebrados (quanto maior, melhor).

Os crackers com a maior pontuação serão declarados vencedores, juntamente com os desenvolvedores das rotinas vencedoras.

Por favor, não decifre sua própria inscrição.

Boa sorte. :)

Entre os melhores

Última atualização em 2 de setembro, 10:45 EST

Barreiras imóveis (envios sem rachaduras):

  1. CJam, 105 [Dennis]

Forças imparáveis ​​(crackers):

  1. Dennis [ Java, 269 ; C 58 ; Mathematica, 29 ]
  2. Martin Büttner [ Java, 245 ]
COTO
fonte
11
Posso sugerir [policiais e ladrões] como a etiqueta para esses desafios? Eu acho que é um nome bastante estabelecido para esses jogos em segurança e provavelmente provocará mais interesse do que adversário.
Martin Ender
Certo. Eu vou mudar agora.
COTO
Que tipo de saída é aceitável? STDOUT, returnetc ...
Ypnypn
2
Seu exemplo está incorreto; sua assinatura é 9.% 5 pode retornar de -4 a 4, inclusive.
Keith Randall
11
@ Dennis Eu ficaria bem com você tentando novamente. Foi minha culpa que isso foi uma bagunça.
Stretch Maniac

Respostas:

7

CJam, 105 bytes

1q~]4G#b2A#md"M-k^XM-WHM-n^GM-0%M-uwM-gM-^XeM-kM-^VO^Ph,M-^MM-^PM-qM-!M-8M-AM-OM-~tM-^FM-cM-h^AM-0M-0M-lM-@M-^[MF=M-^Z^SM-1M-KM-T2M-9M-UmSM-N
M-8M-^^M-n$4M-^M^SM-x M-OM-^@^?"256b@D#Y256#%2+md!A3#*)%)%

O exemplo acima usa circunflexo e notação M, pois contém caracteres não imprimíveis. Depois de converter o fluxo de bytes em um número inteiro ( 256b), o seguinte código é executado:

1q~]4G#b2A#md
12313030820310059479144347891900383683119627474072658988524821209446180284434934346766561958060381533656780340359503554566598728599799248566073353154035839
@D#Y256#%2+md!A3#*)%)%

Você pode experimentar esta versão online no intérprete CJam .

Como funciona

Essa submissão usa a teoria dos números em vez da ofuscação. O programa retornará 0 para quase todas as entradas. Das poucas entradas que resultam em uma saída diferente de zero, é derivado um módulo secreto que é aplicado aos 10 bits menos significativos do terceiro número inteiro.

A maneira mais eficiente de resolver esse desafio (que eu possa pensar) seria fatorar o número inteiro de 512 bits, que espero que não seja possível em 72 horas.

" Prepend 1 to the numbers read from STDIN and convert the resulting array into an integer
  (“N”) by considering them digits of a base 2**32 number.                                 ";

1q~]4G#

" Compute “N / 1024” and “N % 1024”.                                                       ";

2A#md

" Push a carefully selected 512 bit semi-prime (“S”).                                      ";

12313030820310059479144347891900383683119627474072658988524821209446180284434934346766561958060381533656780340359503554566598728599799248566073353154035839

" Compute P = (N / 1024) ** 13 % 2 ** 256 + 2.                                             ";

@D#Y256#%2+

" Compute “S / P” and “S % P”.                                                             ";

md

" Compute “M = (S / P) % (1000 * !(S % P) + 1) + 1”.

  “M” is the key if P is a divisor of S; otherwise, “M == 1”.                              ";

!A3#*)%)

" Compute the final output: “N % 1024 % M”.                                                ";

%

Exemplo de execução

$ base64 -d > outputs.cjam <<< MXF+XTRHI2IyQSNtZCLrGNdI7gewJfV355hl65ZPEGgsjZDxobjBz/50huPoAbCw7MCbTUY9mhOxy9QyudVtU84KuJ7uJDSNE/ggz4B/IjI1NmJARCNZMjU2IyUyK21kIUEzIyopJSkl
$ wc -c outputs.cjam
105 outputs.cjam
$ LANG=en_US cjam outputs.cjam < outputs.secret; echo
1
$ LANG=en_US cjam outputs.cjam <<< '1 2 3'; echo
0
Dennis
fonte
Você é muito bom com o material de criptografia. ;)
COTO
11
"Esta submissão usa teoria dos números em vez de ofuscação." Olha o código "Hmm, certo".
ɐɔıʇǝɥʇuʎs
4

Java - 269

Obrigado pela paciência de todos, isso agora deve ser corrigido.

encurtado:

int a(int a,int b,int c){double d=180-360.0/(int)(Math.abs(Math.sin(a*60))*50+2),e=180-360.0/(int)(Math.abs(Math.cos(b*60))*50+2),f=180-360.0/(int)(Math.atan2(c*60, a*60)*51+2);if(Math.abs(d+e+f-360)<.1)return Integer.valueOf((int)d+""+(int)e+""+(int)f);else return 1;}

Não reduzido:

int a(int a, int b, int c) {
    double d = 180 - 360.0 / (int) (Math.abs(Math.sin(a * 60)) * 50 + 2);
    double e = 180 - 360.0 / (int) (Math.abs(Math.cos(b * 60)) * 50 + 2);
    double f = 180 - 360.0 / (int) (Math.atan2(c * 60, a * 60) * 51 + 2);
    if (Math.abs(d + e + f - 360) < .1)
        return Integer.valueOf((int) d + "" + (int) e + "" + (int) f);
    else
        return 1;
}
Stretch Maniac
fonte
Você pode salvar quatro caracteres alterando double e,f,d=...;e=...;f=...;paradouble d=...,e=...,f=...;
Ypnypn
@Ypnypn Thanks! adicionado à versão golfed.
Stretch Maniac
11
Segunda tentativa ( com permissão explícita ): 122
Dennis
11
@Dennis nice job! (É isso aí) #
Stretch Maniac
11
@Dennis Nesse caso, você está esquecendo 1e sua resposta também está incorreta;) (123 sendo correta ... alguém aparece e pega o placar) ...). E eu acho que Stretch Maniac não foi responsável sin == 1.0quando ele disse que 122 está correto.
Martin Ender
2

Um Sampler

Não é uma entrada oficial, é claro, e a contagem de caracteres é muito alta, mas acho que se alguém quiser um desafio entorpecedor, pode tentar determinar quantas saídas exclusivas a função a seguir produz (com três entradas, conforme descrito no OP) :

function z(y,_,$){M=[];N=[];O=[];C=1792814437;P=72;r=t=0;(f=function(a,k,L){if(k<a.length){for(L=a[k],a[k]=0;a[k]<L;a[k]++)f(a,k+1)}else
if(!t){f([P-1,P-1],0,++t);N=M;while(t<2*P){s=!(t&1);f([P,P,P,P],0,++t);r=r||(s?0:t);t&1&&(N=O);O=[]}}else
((t<2)&&(((d=P*a[0]+(P+1)*a[1]+P)<(P<<6))&&(M[d]=(((y^~_)>>a[0])+((_^~$)>>(a[0]-32)))&1),((a[1]<P-a[0])&&
(M[a[1]+(P+1)*a[0]]=(($^C)>>a[0]+16-a[1])&1))||1))||((t&1)&&((O[P*a[2]+a[3]]|=M[a[1]+P*a[2]]&N[P*a[0]+a[3]]&&
!(a[0]-a[1]))||1))||(s|=N[(a[0]+1)*a[1]+a[3]]);})([],0,0);return r;}

De fato, estou tão confiante de que é imprescindível que concharei a qualquer um que o possua o "Prêmio Força Supremo Incontrolável da Natureza".

Porque realmente, eles merecem.

COTO
fonte
11
Você deve oferecer uma recompensa por isso!
precisa
11
@ Orby Isso seria legal, mas é difícil conceder uma recompensa a um comentário.
Geobits
@COTO esse desafio ainda está em andamento?
Soham Chowdhury
@SohamChowdhury: Absolutamente. Se você descobrir, vou explicar sua vitória no OP. Caso contrário, avise-me e postarei a solução.
COTO
2

C, 58 bytes (rachado)

Um simples:

f(a,b,c){return(long long)a*b*c-0x1d21344f8479d61dLL?0:a;}
Ou por
fonte
2
7 ( -15485867, -1299721, -104287, 0, 104287, 1299721, 15485867).
Dennis
Isso foi rápido :)
Orby
2

Java - 245

Rachado por Martin Büttner

int a(int[]_$){return $($($_(_$[0],0)))+$_(_$[1],1)*11+$($($_(_$[1+1],0)))*(1+1);}int $_(int $,int $_){int OO=0,o=1,O=1;for($=$<0?-$:$;++O*O<=$;OO+=$%O<1?O:0,o+=$%O<1?1:0,$/=$%O<1?O--:1);return $_>0?o:OO+$;}int $(int $){return(int)Math.sqrt($);}

Alimentar a entrada como uma matriz int: a(new int[]{1,2,3}). Não estou esperando 72 horas, mas divirta-se.

Aqui está com quebras de linha, para torná-lo um pouco mais legível:

int a(int[]_$){return $($($_(_$[0],0)))+$_(_$[1],
1)*11+$($($_(_$[1+1],0)))*(1+1);}int $_(int $,int
$_){int OO=0,o=1,O=1;for($=$<0?-$:$;++O*O<=$;OO+=
$%O<1?O:0,o+=$%O<1?1:0,$/=$%O<1?O--:1);return $_>
0?o:OO+$;}int $(int $){return(int)Math.sqrt($);}
Geobits
fonte
Apenas por força bruta ... 90?
Vetorizado
@bitpwner Não, desculpe.
Geobits
11
I deobfuscated-lo um pouco: pastebin.com/8pvvfFYB (. Espero não cometer erros ao substituir nomes de variáveis)
Martin Ender
4
Ok, aqui está a minha tentativa: 965?
Martin Ender
11
@ MartinBüttner Correto. Obrigado pela versão ofuscada: D
Geobits
1

Mathematica, 29 bytes, Chave: 715, Rachado por Dennis

Esta é apenas uma versão fixa da minha resposta inicial, que não funcionou para entradas não positivas.

f=Plus@@Mod[NextPrime@#,240]&

Leva uma lista de números inteiros como

f[{1,2,3}]
Martin Ender
fonte
Encontrei 349saídas únicas. O intervalo foi de 3até 717.
PhiNotPi
@PhiNotPi Wrong. (Verifiquei duas vezes)
Martin Ender
Bem, eu encontrei o meu erro e a resposta certa. Tarde demais.
PhiNotPi
11
Se o material que reuni na documentação do Mathematica e no WolframAlpha estiver correto, a chave será 715 ( 3 ... 717).
Dennis
2
Mathematica parece com uma linguagem agradável, mas é demasiado danado caro ou que eu sou muito danado barato ...
Dennis
0

207 caracteres, em C / C ++, ainda não ofuscados:

int x(int a, int b, int c) {
    int d, e, f;
    for (int i=0; i!=1<<31; ++i) {
        d=10*(b-a);
        e=a*(28-c)-b;
        f=a*b-2.7*c;
        a += d;
        b += e;
        c += f;
    }
    return ((a%5+5)*10+(b%5+5))*10+c%5+5;
}
ldgabbay
fonte
Apenas tentando a minha sorte ... 729.
Vectorized
@bitpwner Porra, eu ia dizer isso. : D ... Se estiver errado, esse é o limite superior.
Martin Ender
2
Este não é um envio válido. Todas as atribuições dentro do loop podem resultar em estouro de número inteiro assinado , com comportamento indefinido.
Dennis