Concurso Internacional de Código C Ofuscado - International Obfuscated C Code Contest
Concurso Internacional de Código C Ofuscado | |
---|---|
Status | Ativo |
Gênero | Concurso de codificação |
Começa | 26 de dezembro de 2018 |
Termina | 15 de março de 2019 |
Frequência | Anualmente |
Anos ativos | 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015, 2018 até o presente |
Inaugurado | 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); } }
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 .sc
arquivo de cenário via stdin
entrada:
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
- ^ 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 .
- ^ "Vencedores anteriores do IOCCC" . IOCCC. 2014. Arquivado do original em 2013-12-23 . Recuperado em 08/01/2014 .
- ^ a b c "Diretrizes para 2015" (texto simples) . IOCCC. 2015 . Página visitada em 2015-11-20 .
- ^ "FAQ" . IOCCC . Página visitada em 2011-11-12 .
- ^ "Top Execs falham ao calcular corretamente" . San Jose Mercury News , Califórnia. 15 de maio de 1993. p. 1A. Via Newsbank . (assinatura necessária)
- ^ 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 .
- ^ Swaine, Michael (1º de maio de 2008). "Deve haver concurso" . Diário do Dr. Dobb . Página visitada em 07-04-2013 .
- ^ Página inicial do IOCCC, rodapé e em cada arquivo hint.txt
- ^ Spinellis, Diomidis (5 de outubro de 2006). "Code Finessing" . Diário do Dr. Dobb . Página visitada em 07-04-2013 .
- ^ IOCCC 2004 - O melhor abuso de CPP IOCCC. Retirado 2013-04-08.
- ^ "smr.hint" (texto simples) . IOCCC. 1994 . Página visitada em 2006-09-16 .
- ^ "gavin.hint3" (texto simples) . IOCCC. 2004 . Página visitada em 01-03-2007 .
- ^ Toledo Nanochess e Toledo Picochess
- ^ Quem ganhou o 18º IOCCC
- ^ Versão parcialmente desofuscada do Nanochess
- ^ Toledo Gutiérrez, Oscar (2014). Toledo Nanochess: O código-fonte comentado . Lulu . ISBN 978-1-304-86437-6.
- ^ http://smmax.sourceforge.net/
- ^ Super Micro FIDE 760
- ^ "westley.c" , 5º Concurso Internacional de Código C ofuscado 1988 Arquivado em 22/10/2013 na Wayback Machine ). IOCCC.
-
^ usando gcc, compilar com a seguinte linha de comando:
gcc -traditional-cpp -o r r.c
ougcc -E r.c | sed 's/- -/--/g' > r2.c ; gcc -o r2 r2.c
(O arquivo fonte ér.c
) - ^ a b c IOCCC Flight Simulator . aerojockey.com. Retirado 2013-04-08.
- ^ 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.
- ^ "Índice de / 2011 / akari" . www.ioccc.org . Recuperado em 2020-09-18 .