Concurso Internacional de Código C Ofuscado - International Obfuscated C Code Contest

Concurso Internacional de Código C Ofuscado
IOCCC.png
O logotipo do IOCCC
Status Ativo
Gênero Concurso de codificação
Começa 26 de dezembro de 2018 ( 26/12/2018 )
Termina 15 de março de 2019 ( 15/03/2019 )
Frequência Anualmente
Anos ativos 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015, 2018 até o presente
Inaugurado 1984 ( 1984 )
Fundadores Landon Curt Noll , Larry Bassel
Local na rede Internet www.ioccc.org

O Concurso Internacional de Código C Ofuscado (abreviado IOCCC ) é um concurso de programação de computador para o código C ofuscado com mais criatividade . Realizado anualmente, é descrito como "celebrando opacidade sintática [C's]". O código vencedor para o 27º concurso, realizado em 2020, foi lançado em julho de 2020. Os concursos anteriores foram realizados nos anos 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015 e 2018–2020.

As inscrições são avaliadas anonimamente por um painel de juízes. O processo de julgamento é documentado nas diretrizes da competição e consiste em rodadas eliminatórias. Por tradição, nenhuma informação é fornecida sobre o número total de inscrições para cada competição. As inscrições vencedoras são premiadas com uma categoria, como "Pior Abuso do pré-processador C " ou "Comportamento Mais Errático", e então anunciadas no site oficial do IOCCC. O concurso afirma que ser anunciado no site do IOCCC é a recompensa pela vitória.

História

O IOCCC foi fundado por Landon Curt Noll e Larry Bassel em 1984 enquanto trabalhava no grupo de portabilidade Genix da National Semiconductor. A ideia do concurso surgiu depois que eles compararam notas entre si sobre alguns códigos mal escritos que eles tiveram que consertar, notavelmente o shell Bourne , que usava macros para emular a sintaxe do ALGOL 68 , e uma versão com bugs do finger para BSD. O próprio concurso foi o tema de um questionário no Computer Bowl de 1993. Após um hiato de cinco anos a partir de 2006, o concurso voltou em 2011.

Comparado com outros concursos de programação, o IOCCC é descrito como "não tão sério" por Michael Swaine , editor do Dr. Dobb's Journal .

Regras

A cada ano, as regras do concurso são publicadas no site do IOCCC. Todo o material é publicado sob a licença Creative Commons BY-SA 3.0 Unported. As regras variam de ano para ano e são publicadas com um conjunto de diretrizes que tentam transmitir o espírito das regras.

Hackear as regras do concurso é uma tradição. - Landon Curt Noll, 2011

As regras são freqüentemente escritas deliberadamente com brechas que os competidores são encorajados a encontrar e abusar. Inscrições que aproveitam brechas podem fazer com que as regras do concurso do ano seguinte sejam ajustadas.

Ofuscações empregadas

As entradas geralmente empregam truques estranhos ou incomuns, como usar o pré-processador C para fazer coisas que não foram projetadas para fazer (em alguns casos "espetacularmente", de acordo com o Dr. Dobbs , com uma entrada criando uma ALU de 11 bits no pré-processador C ), ou evitando construções comumente usadas na linguagem de programação C em favor de maneiras muito mais obscuras de alcançar a mesma coisa.

As contribuições incluíram código-fonte formatado para se parecer com imagens, texto, etc., à maneira da arte ASCII , redefinições do pré-processador para tornar o código mais difícil de ler e código que se modifica automaticamente . Em vários anos, foi enviada uma inscrição que exigia uma nova definição de algumas das regras para o ano seguinte. Isso é considerado uma grande honra. Um exemplo é o programa de auto-reprodução mais curto do mundo . A entrada era um programa projetado para produzir seu próprio código-fonte e que tinha zero bytes de código-fonte. Quando o programa foi executado, ele imprimiu zero bytes, equivalente ao seu código-fonte.

No esforço de levar a ofuscação a seus extremos, os concorrentes produziram programas que contornam os limites dos padrões C ou resultam em construções que acionam combinações de caminhos de código raramente usadas em compiladores. Como resultado, várias das entradas anteriores podem não ser compiladas diretamente em um compilador moderno e algumas podem causar travamentos.

Exemplos

Dentro do limite de tamanho do código de apenas alguns kilobytes, os competidores conseguiram fazer coisas complicadas - um vencedor de 2004 produziu um sistema operacional.

Toledo Nanochess

Toledo Nanochess é uma máquina de xadrez desenvolvida pelo mexicano Oscar Toledo Gutiérrez, cinco vezes vencedor do IOCCC. De acordo com as regras do IOCCC, tem 1255 caracteres. O autor afirma que é o menor programa de xadrez do mundo escrito em C.

O código-fonte do Toledo Nanochess e outros engines está disponível. Como o Toledo Nanochess é baseado na entrada vencedora de Toledo no 18º IOCCC (Melhor Jogo), ele é fortemente ofuscado .

Em 2 de fevereiro de 2014, o autor publicou o livro Toledo Nanochess: O código-fonte comentado , que contém o código-fonte totalmente comentado.

Em 7 de fevereiro de 2010, parecia ser um dos dois únicos motores de xadrez escritos em menos de 2 kilobytes de C que são capazes de jogar movimentos de xadrez legais completos, junto com Micro-Max do físico holandês HG Muller. Em 2014, a barreira de 1 kilobyte foi quebrada pelo Super Micro Chess - um derivado do Micro-Max - totalizando 760 caracteres (espaços e novas linhas incluídos). Há também uma versão menor do motor de Toledo, o Toledo Picochess , que consiste em 944 caracteres não vazios.

Trecho do código fonte

B,i,y,u,b,I[411],*G=I,x=10,z=15,M=1e4;X(w,c,h,e,S,s){int t,o,L,E,d,O=e,N=-M*M,K
=78-h<<x,p,*g,n,*m,A,q,r,C,J,a=y?-x:x;y^=8;G++;d=w||s&&s>=h&&v 0,0)>M;do{_ o=I[
p=O]){q=o&z^y _ q<7){A=q--&2?8:4;C=o-9&z?q["& .$  "]:42;do{r=I[p+=C[l]-64]_!w|p
==w){g=q|p+a-S?0:I+S _!r&(q|A<3||g)||(r+1&z^y)>9&&q|A>2){_ m=!(r-2&7))P G[1]=O,
K;J=n=o&z;E=I[p-a]&z;t=q|E-7?n:(n+=2,6^y);Z n<=t){L=r?l[r&7]*9-189-h-q:0 _ s)L
+=(1-q?l[p/x+5]-l[O/x+5]+l[p%x+6]*-~!q-l[O%x+6]+o/16*8:!!m*9)+(q?0:!(I[p-1]^n)+
!(I[p+1]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^9)_ s>h||1<s&s==h&&L>z|d){p[I]=n,O
[I]=m?*g=*m,*m=0:g?*g=0:0;L-=X(s>h|d?0:p,L-N,h+1,G[1],J=q|A>1?0:p,s)_!(h||s-1|B
-O|i-n|p-b|L<-M))P y^=8,u=J;J=q-1|A<7||m||!s|d|r|o<z||v 0,0)>M;O[I]=o;p[I]=r;m?
*m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ s>1){_ h&&c-L<0)P L _!h)i=n,B=O,b=p;}N=L;}
n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-p]||I[p+=p-O]);}}}}Z!r&q>2||(p=O,q|A>2|o>z&
!r&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N>-K+1924|d?N:0;}main(){Z++B<121)*G
++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&31;Z B=19){Z B++<99)putchar(B%x?l[B[I]|16]:x)_
x-(B=F)){i=I[B+=(x-F)*x]&z;b=F;b+=(x-F)*x;Z x-(*G=F))i=*G^8^y;}else v u,5);v u,
1);}}

Pi

Abaixo está uma entrada de 1988 que calcula pi olhando para sua própria área :

#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
            _-_-_-_
       _-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
  _-_-_-_-_-_-_-_-_-_-_-_-_-_
    _-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_
            _-_-_-_
}

(Esta entrada foi escrita em K&R C ; não funciona corretamente em ANSI C sem algumas alterações.)

Simulador de voo

Outro exemplo é o seguinte simulador de vôo, o vencedor do IOCCC de 1998, conforme listado e descrito em Apostas calculadas: computadores, jogos de azar e modelagem matemática para ganhar (2001) e mostrado abaixo:

#include                                     <math.h>
#include                                   <sys/time.h>
#include                                   <X11/Xlib.h>
#include                                  <X11/keysym.h>
                                          double L ,o ,P
                                         ,_=dt,T,Z,D=1,d,
                                         s[999],E,h= 8,I,
                                         J,K,w[999],M,m,O
                                        ,n[999],j=33e-3,i=
                                        1E3,r,t, u,v ,W,S=
                                        74.5,l=221,X=7.26,
                                        a,B,A=32.2,c, F,H;
                                        int N,q, C, y,p,U;
                                       Window z; char f[52]
                                    ; GC k; main(){ Display*e=
 XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
 *D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
  XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
                                   XEvent z; XNextEvent(e ,&z);
                                       ++*((N=XLookupKeysym
                                         (&z.xkey,0))-IT?
                                         N-LT? UP-N?& E:&
                                         J:& u: &h); --*(
                                         DN -N? N-DT ?N==
                                         RT?&u: & W:&h:&J
                                          ); } m=15*F/l;
                                          c+=(I=M/ l,l*H
                                          +I*M+a*X)*_; H
                                          =A*r+v*X-F*l+(
                                          E=.1+X*4.9/l,t
                                          =T*m/32-I*T/24
                                           )/S; K=F*M+(
                                           h* 1e4/l-(T+
                                           E*5*T*E)/3e2
                                           )/S-X*d-B*A;
                                           a=2.63 /l*d;
                                           X+=( d*l-T/S
                                            *(.19*E +a
                                            *.64+J/1e3
                                            )-M* v +A*
                                            Z)*_; l +=
                                            K *_; W=d;
                                            sprintf(f,
                                            "%5d  %3d"
                                            "%7d",p =l
                                           /1.7,(C=9E3+
                              O*57.3)%0550,(int)i); d+=T*(.45-14/l*
                             X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
                             *I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
                             179*v)/2312; select(p=0,0,0,0,&G); v-=(
                              W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
                               )/107e2)*_; D=cos(o); E=sin(o); } }
Cenário Pittsburgh do simulador de vôo

Este programa precisa da seguinte linha de comando em um sistema Linux para ser compilado:

cc banks.c -o banks -DIT=XK_Page_Up -DDT=XK_Page_Down \
	-DUP=XK_Up -DDN=XK_Down -DLT=XK_Left -DRT=XK_Right \
	-DCS=XK_Return -Ddt=0.02 -lm -lX11 -L/usr/X11R6/lib

Para executar o arquivo binário ( banks), ele deve ser fornecido com um .scarquivo de cenário via stdinentrada:

 cat pittsburgh.sc | ./banks

Akari

Abaixo está uma entrada de 2011 que reduz a resolução de uma imagem ASCII de Don, Yang:

                                       /*
                                      +
                                     +
                                    +
                                    +
                                    [         >i>n[t
                                     */   #include<stdio.h>
                        /*2w0,1m2,]_<n+a m+o>r>i>=>(['0n1'0)1;
                     */int/**/main(int/**/n,char**m){FILE*p,*q;int        A,k,a,r,i/*
                   #uinndcelfu_dset<rsitcdti_oa.nhs>i/_*/;char*d="P%"   "d\n%d\40%d"/**/
                 "\n%d\n\00wb+",b[1024],y[]="yuriyurarararayuruyuri*daijiken**akkari~n**"
          "/y*u*k/riin<ty(uyr)g,aur,arr[a1r2a82*y2*/u*r{uyu}riOcyurhiyua**rrar+*arayra*="
       "yuruyurwiyuriyurara'rariayuruyuriyuriyu>rarararayuruy9uriyu3riyurar_aBrMaPrOaWy^?"
      "*]/f]`;hvroai<dp/f*i*s/<ii(f)a{tpguat<cahfaurh(+uf)a;f}vivn+tf/g*`*w/jmaa+i`ni("/**
     */"i+k[>+b+i>++b++>l[rb";int/**/u;for(i=0;i<101;i++)y[i*2]^="~hktrvg~dmG*eoa+%squ#l2"
     ":(wn\"1l))v?wM353{/Y;lgcGp`vedllwudvOK`cct~[|ju {stkjalor(stwvne\"gt\"yogYURUYURI"[
     i]^y[i*2+1]^4;/*!*/p=(n>1&&(m[1][0]-'-'||m[1][1]  !='\0'))?fopen(m[1],y+298):stdin;
      /*y/riynrt~(^w^)],]c+h+a+r+*+*[n>)+{>f+o<r<(-m]    =<2<5<64;}-]-(m+;yry[rm*])/[*
       */q=(n<3||!(m[2][0]-'-'||m[2][1]))?stdout /*]{     }[*/:fopen(m[2],d+14);if(!p||/*
       "]<<*-]>y++>u>>+r >+u+++y>--u---r>++i+++"  <)<      ;[>-m-.>a-.-i.++n.>[(w)*/!q/**/)
    return+printf("Can "  "not\x20open\40%s\40"    ""       "for\40%sing\n",m[!p?1:2],!p?/*
  o=82]5<<+(+3+1+&.(+  m  +-+1.)<)<|<|.6>4>-+(>    m-        &-1.9-2-)-|-|.28>-w-?-m.:>([28+
 */"read":"writ");for  (   a=k=u= 0;y[u];  u=2    +u){y[k++   ]=y[u];}if((a=fread(b,1,1024/*
,mY/R*Y"R*/,p/*U*/)/*          R*/ )>/*U{  */   2&& b/*Y*/[0]/*U*/=='P' &&4==/*"y*r/y)r\}
*/sscanf(b,d,&k,& A,&           i,  &r)&&        !   (k-6&&k -5)&&r==255){u=A;if(n>3){/*
]&<1<6<?<m.-+1>3> +:+ .1>3+++     .   -m-)      -;.u+=++.1<0< <; f<o<r<(.;<([m(=)/8*/
u++;i++;}fprintf   (q,    d,k,           u      >>1,i>>1,r);u  = k-5?8:4;k=3;}else
  /*]>*/{(u)=/*{   p> >u  >t>-]s                >++(.yryr*/+(    n+14>17)?8/4:8*5/
     4;}for(r=i=0  ;  ;){u*=6;u+=                (n>3?1:0);if    (y[u]&01)fputc(/*
      <g-e<t.c>h.a r  -(-).)8+<1.                 >;+i.(<)<     <)+{+i.f>([180*/1*
      (r),q);if(y[u   ]&16)k=A;if                               (y[u]&2)k--;if(i/*
      ("^w^NAMORI; {   I*/==a/*"                               )*/){/**/i=a=(u)*11
       &255;if(1&&0>=     (a=                                 fread(b,1,1024,p))&&
        ")]i>(w)-;} {                                         /i-f-(-m--M1-0.)<{"
         [ 8]==59/* */                                       )break;i=0;}r=b[i++]
            ;u+=(/**>>                                     *..</<<<)<[[;]**/+8&*
            (y+u))?(10-              r?4:2):(y[u]         &4)?(k?2:4):2;u=y[u/*
             49;7i\(w)/;}             y}ru\=*ri[        ,mc]o;n}trientuu ren (
             */]-(int)'`';}             fclose(          p);k= +fclose( q);
              /*] <*.na/m*o{ri{                       d;^w^;}  }^_^}}
               "   */   return  k-                -1+   /*\'   '-`*/
                     (   -/*}/   */0x01        );       {;{    }}
                            ;           /*^w^*/        ;}

Se o programa for executado usando sua própria fonte como entrada, o resultado será:

[root@host ~]# ./akari akari.c 
                   
                  
                       int
            *w,m,_namori=('n');
         #include<stdio.h>/*;hrd"%  dnd4%"*/
     /**/int(y),u,r[128*2/*{y}icuhya*rr*rya=
   */];void/**/i(){putchar(u);}int/**/main(/*
  "(n"l)?M5{YlcpvdluvKct[j skao(tve"t"oYRYR"
   */int(w),char**n){for(m  =256;--m;r[m]/*
   "<*]y+u>r>u+y-u-r+i+" )   ;>m.a.i+n>()/q*/
 =25<(31&( m -1))||64-(  m    &192)||2>w?m:(2+
m/*"*,/U//     R/)/U *  & /Y/0/U/=P &=/"*/)\
&16?m-13 : 13+     m)   ;u=+10 ;for(;(m=/*
 *>/()/{ p u t-s        +(yy*+  n1>7?/:*/
   getchar ())+1         ;i()   ){if(10/*
   "wNMR;{ I/=/"               )/{*/==u*1
    )i();                      if(m-10){
      u=/*>                  *./<)[;*/8*
      4;i();       }u=r[    m];}return(
       * *n/*{i            ;w; }_}
          ( -*/ *00    )    ;  }
[root@host ~]# ./akari akari.c > ./akari.small
[root@host ~]# ./akari ./akari.small 
         
      wm_aoi(n)
  /*ity,,[2*/{}char*y=
 (")M{lpduKtjsa(v""YY"
 "*yuruyuri") ;main(/*
/",U/  R)U*  Y0U= ="/\
*/){puts    (y+ 17/*
 "NR{I="       ){/=*
   =*         */);/*
   **/{      ;;}}
[root@host ~]# 
[root@host ~]# ./akari ./akari.small > ./akari.smaller
[root@host ~]# ./akari ./akari.smaller
   main
(){puts("Y"
"U RU YU "\
"RI"   )/*
 */   ;}
[root@host ~]#

Veja também

Notas e referências

  1. ^ Palmer, Geoff (1 ° de novembro de 2004). "Além da linha de comando" . PC World Nova Zelândia . Arquivado do original em 10 de fevereiro de 2013 . Página visitada em 07-04-2013 .
  2. ^ "Vencedores anteriores do IOCCC" . IOCCC. 2014. Arquivado do original em 2013-12-23 . Recuperado em 08/01/2014 .
  3. ^ a b c "Diretrizes para 2015" (texto simples) . IOCCC. 2015 . Página visitada em 2015-11-20 .
  4. ^ "FAQ" . IOCCC . Página visitada em 2011-11-12 .
  5. ^ "Top Execs falham ao calcular corretamente" . San Jose Mercury News , Califórnia. 15 de maio de 1993. p. 1A. Via Newsbank . (assinatura necessária)
  6. ^ a b Jackson, Joab (15 de novembro de 2011). "Retornos do concurso de código ofuscado" . PC World . Página visitada em 07-04-2013 .
  7. ^ Swaine, Michael (1º de maio de 2008). "Deve haver concurso" . Diário do Dr. Dobb . Página visitada em 07-04-2013 .
  8. ^ Página inicial do IOCCC, rodapé e em cada arquivo hint.txt
  9. ^ Spinellis, Diomidis (5 de outubro de 2006). "Code Finessing" . Diário do Dr. Dobb . Página visitada em 07-04-2013 .
  10. ^ IOCCC 2004 - O melhor abuso de CPP IOCCC. Retirado 2013-04-08.
  11. ^ "smr.hint" (texto simples) . IOCCC. 1994 . Página visitada em 2006-09-16 .
  12. ^ "gavin.hint3" (texto simples) . IOCCC. 2004 . Página visitada em 01-03-2007 .
  13. ^ Toledo Nanochess e Toledo Picochess
  14. ^ Quem ganhou o 18º IOCCC
  15. ^ Versão parcialmente desofuscada do Nanochess
  16. ^ Toledo Gutiérrez, Oscar (2014). Toledo Nanochess: O código-fonte comentado . Lulu . ISBN 978-1-304-86437-6.
  17. ^ http://smmax.sourceforge.net/
  18. ^ Super Micro FIDE 760
  19. ^ "westley.c" , 5º Concurso Internacional de Código C ofuscado 1988 Arquivado em 22/10/2013 na Wayback Machine ). IOCCC.
  20. ^ usando gcc, compilar com a seguinte linha de comando:gcc -traditional-cpp -o r r.cougcc -E r.c | sed 's/- -/--/g' > r2.c ; gcc -o r2 r2.c(O arquivo fonte ér.c)
  21. ^ a b c IOCCC Flight Simulator . aerojockey.com. Retirado 2013-04-08.
  22. ^ Skiena, Steven (2001). Apostas calculadas: computadores, jogos de azar e modelagem matemática para ganhar . The Mathematical Association of America. pp.  152 , 153. ISBN 978-0521009621.
  23. ^ "Índice de / 2011 / akari" . www.ioccc.org . Recuperado em 2020-09-18 .

links externos