Sorties deux-plusieurs

17

Le défi

Je vous présente un autre défi espion contre espion opposant les obfuscateurs aux crackers. Dans ce cas, cependant, la donnée à protéger n'est pas une entrée mais une sortie .

Les règles du défi sont simples. Écrivez une routine avec les spécifications suivantes:

  1. La routine peut être écrite dans n'importe quelle langue mais ne doit pas dépasser 320 octets.
  2. La routine doit accepter trois entiers signés 32 bits comme entrées. Il peut prendre la forme d'une fonction qui accepte 3 arguments, une fonction qui accepte un seul tableau à 3 éléments ou un programme complet qui lit 3 entiers à partir de n'importe quelle entrée standard.
  3. La routine doit générer un entier 32 bits signé.
  4. Sur toutes les entrées possibles, la routine doit sortir entre 2 et 1 000 (inclus) valeurs uniques. Le nombre de valeurs uniques qu'une routine peut produire est appelé sa clé .

Par exemple, le programme C

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

a une clé de 9, car elle (je l' espère) peut sortir les neuf valeurs 16, 17, 18, 19, 20, 21, 22, 23et 24.

Certaines limitations supplémentaires sont les suivantes:

  1. La routine doit être entièrement déterministe et invariante dans le temps, renvoyant des sorties identiques pour des entrées identiques. La routine ne doit pas appeler les générateurs de nombres pseudo-aléatoires.
  2. La routine peut ne pas s'appuyer sur des "variables cachées" telles que des données dans des fichiers, des variables système ou des fonctionnalités de langage ésotérique. Par exemple, les routines ne devraient généralement pas faire référence à des constantes à moins que les constantes ne soient clairement définies dans le code lui-même. Les routines qui s'appuient sur des caprices du compilateur, des sorties d'opérations mathématiques non définies, des erreurs arithmétiques, etc. sont également fortement déconseillées. En cas de doute, s'il vous plaît demander.
  3. Vous (le codeur) devez savoir précisément combien de sorties uniques la routine peut produire et devez être en mesure de fournir au moins une séquence d'entrée qui produit chaque sortie. (Puisqu'il peut potentiellement y avoir des centaines de sorties uniques, cet ensemble ne sera jamais demandé que si votre clé est contestée.)

Étant donné que ce problème ressemble beaucoup moins à un cryptage classique que le précédent, je m'attends à ce qu'il soit accessible à un public plus large.

Plus c'est créatif, mieux c'est.

La notation

La ou les soumissions non fissurées les plus courtes par décompte d'octets seront déclarées gagnantes.

En cas de confusion, n'hésitez pas à demander ou à commenter.

Le contre-défi

Tous les lecteurs, y compris ceux qui ont soumis leurs propres routines, sont encouragés à "cracker" les soumissions. Une soumission est craquée lorsque sa clé est publiée dans la section des commentaires associés. Si une soumission persiste pendant 72 heures sans être modifiée ou fêlée, elle est considérée comme «sûre» et tout succès ultérieur dans la fêlure sera ignoré pour les besoins du concours.

Une seule tentative de piratage par soumission par lecteur est autorisée. Par exemple, si je soumets à l'utilisateur X: "votre clé est 20" et que je me trompe, l'utilisateur X rejette ma supposition comme incorrecte et je ne pourrai plus soumettre de suppositions supplémentaires pour cette soumission.

Les soumissions fissurées sont éliminées de la contention (à condition qu'elles ne soient pas «sécuritaires»). Ils ne doivent pas être modifiés. Si un lecteur souhaite soumettre une nouvelle routine, il doit le faire dans une réponse séparée.

Le score d'un cracker est le nombre de soumissions (conformes ou non) qu'il ou elle cracke. Pour les crackers avec des nombres identiques, le classement est déterminé par le nombre total d'octets dans toutes les soumissions fissurées (le plus élevé, le meilleur).

Le ou les crackers avec le ou les scores les plus élevés seront déclarés gagnants avec les développeurs des routines gagnantes.

Veuillez ne pas casser votre propre soumission.

Bonne chance. :)

Classement

Dernière mise à jour le 2 septembre à 10 h 45 HNE

Barrières inamovibles (soumissions non fissurées):

  1. CJam, 105 [Dennis]

Forces imparables (craquelins):

  1. Dennis [ Java, 269 ; C, 58 ; Mathematica, 29 ]
  2. Martin Büttner [ Java, 245 ]
COTO
la source
11
Puis-je suggérer [flics-and-volers] comme balise pour ces défis? Je pense que c'est un nom assez établi pour de tels jeux de sécurité et cela suscitera probablement plus d'intérêt que [adversarial].
Martin Ender
Sûr. Je vais le changer maintenant.
COTO
Quel type de sortie est acceptable? STDOUT return
,,
2
Votre exemple est incorrect; sa signature est de 9.% 5 peut renvoyer n'importe quoi de -4 à 4 inclus.
Keith Randall
1
@Dennis, je serais d'accord pour que vous essayiez à nouveau. C'était ma faute si c'était foiré.
Stretch Maniac

Réponses:

7

CJam, 105 octets

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#*)%)%

Ce qui précède utilise le signe d'insertion et la notation M, car il contient un caractère non imprimable. Après avoir converti le flux d'octets en un entier (256b ), le code suivant est exécuté:

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

Vous pouvez essayer cette version en ligne dans le interpréteur CJam .

Comment ça fonctionne

Cette soumission utilise la théorie des nombres au lieu de l'obscurcissement. Le programme renverra 0 pour presque toutes les entrées. Des quelques entrées qui produisent une sortie non nulle, un module secret est dérivé qui est appliqué aux 10 bits les moins significatifs du troisième entier.

La façon la plus efficace de résoudre ce défi (à laquelle je pense) serait de factoriser l'entier 512 bits, ce qui, je l'espère, ne sera pas réalisable en 72 heures.

" 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”.                                                ";

%

Exemple d'exécution

$ 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
la source
Vous êtes tout simplement trop bon avec le chiffrement. ;)
COTO
11
"Cette soumission utilise la théorie des nombres au lieu de l'obscurcissement." Regarde le code "Hmm, à droite."
ɐɔıʇǝɥʇuʎs
4

Java - 269

Merci pour la patience de tout le monde, cela devrait maintenant être corrigé.

raccourci:

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

Non raccourci:

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
la source
Vous pouvez enregistrer quatre personnages en changeant double e,f,d=...;e=...;f=...;àdouble d=...,e=...,f=...;
Ypnypn
@Ypnypn Merci! ajouté à la version golfée.
Stretch Maniac
1
Deuxième tentative ( avec autorisation explicite ): 122
Dennis
1
@Dennis beau travail! (C'est tout)
Stretch Maniac
1
@Dennis Dans ce cas, vous oubliez 1et votre réponse est également incorrecte;) (123 étant correct ... quelqu'un arrive et récupère le score de cracking). Et je suppose que Stretch Maniac n'a pas tenu compte sin == 1.0quand il a dit que 122 était correct.
Martin Ender du
2

Un échantillonneur

Ce n'est pas une entrée officielle bien sûr, et le nombre de caractères est trop élevé, mais je pense que si quelqu'un veut un défi époustouflant, il peut essayer de déterminer combien de sorties uniques la fonction suivante produit (compte tenu de trois entrées décrites dans l'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;}

En fait, je suis tellement convaincu qu'il est impossible de craquer, je décernerai à quiconque le craquera le "Prix suprême de la force imparable de la nature".

Parce que vraiment, ils le méritent.

COTO
la source
1
Vous devriez mettre en place une prime pour cela!
Orby
1
@Orby Ce serait bien, mais il est difficile d'attribuer une prime à un commentaire.
Geobits
@COTO ce défi est-il toujours d'actualité?
Soham Chowdhury du
@SohamChowdhury: Absolument. Si vous le comprenez, je vais exposer votre victoire au PO. Sinon, faites-le moi savoir et je publierai la solution.
COTO
2

C, 58 octets (fissuré)

Un simple:

f(a,b,c){return(long long)a*b*c-0x1d21344f8479d61dLL?0:a;}
Orby
la source
2
7 ( -15485867, -1299721, -104287, 0, 104287, 1299721, 15485867).
Dennis
C'était rapide :)
Orby
2

Java - 245

Craqué par 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($);}

Alimentez l'entrée en tant que tableau int: a(new int[]{1,2,3}) . Je ne m'attends pas à ce que ça dure 72 heures, mais amusez-vous avec.

Le voici avec des sauts de ligne, pour le rendre un peu plus lisible:

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($);}
Géobits
la source
Rien que de la force brute ... 90?
vectorisé
@bitpwner Nope, désolé.
Geobits
1
Je l'ai désobscurci un peu: pastebin.com/8pvvfFYB (j'espère que je n'ai fait aucune erreur en remplaçant les noms de variables.)
Martin Ender
4
D'accord, voici ma tentative: 965?
Martin Ender
1
@ MartinBüttner Correct. Merci pour la version obscurcie: D
Geobits
1

Mathematica, 29 octets, clé: 715, fissuré par Dennis

Ceci est juste une version fixe de ma réponse initiale, qui ne fonctionnait pas pour les entrées non positives.

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

Prend une liste d'entiers comme

f[{1,2,3}]
Martin Ender
la source
J'ai trouvé 349des sorties uniques. La plage allait de 3à 717.
PhiNotPi
@PhiNotPi Wrong. (J'ai revérifié)
Martin Ender
Eh bien, j'ai trouvé mon erreur et la bonne réponse. Trop tard cependant.
PhiNotPi
1
Si les éléments que j'ai rassemblés à partir de la documentation Mathematica et de WolframAlpha sont corrects, la clé est 715 ( 3 ... 717).
Dennis
2
Mathematica ressemble à une belle langue, mais c'est trop cher ou je suis trop bon marché ...
Dennis
0

207 caractères, en C / C ++, pas encore obscurcis:

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
la source
Je tente ma chance ... 729.
vectorisé
@bitpwner Damn, j'allais juste dire ça. : D ... Si c'est faux, c'est la limite supérieure.
Martin Ender
2
Ce n'est pas une soumission valide. Toutes les affectations à l'intérieur de la boucle peuvent entraîner un débordement d'entier signé , qui a un comportement non défini.
Dennis