Mezinárodní soutěž o zmatený kód C - International Obfuscated C Code Contest

Mezinárodní soutěž o zmatený kód C.
IOCCC.png
Logo IOCCC
Postavení Aktivní
Žánr Soutěž o kódování
Začíná 26. prosince 2018 ( 26. 12. 2018 )
Končí 15. března 2019 ( 2019-03-15 )
Frekvence Každoročně
Aktivní roky 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015, 2018-současnost
Slavnostně otevřeno 1984 ( 1984 )
Zakladatelé Landon Curt Noll , Larry Bassel
webová stránka www.ioccc.org

The International Obfuscated C Code Contest (zkráceně IOCCC ) je soutěž počítačového programování o nejkreativněji zmatený C kód . Koná se každoročně a je popisován jako „oslavující [C] syntaktickou neprůhlednost“. Vítězný kód pro 27. soutěž, která se konala v roce 2020, byla zveřejněna v červenci 2020. Předchozí soutěže se konaly v letech 1984–1996, 1998, 2000, 2001, 2004–2006, 2011–2015 a 2018–2020.

Přihlášky hodnotí anonymně porota. Proces hodnocení je dokumentován v pravidlech soutěže a sestává z vyřazovacích kol. Tradičně nejsou uvedeny žádné informace o celkovém počtu přihlášených do každé soutěže. Vítězné příspěvky jsou oceněny kategorií, jako je „Nejhorší zneužívání preprocesoru C “ nebo „Nejnepravidelnější chování“, a poté jsou vyhlášeny na oficiálních webových stránkách IOCCC. Soutěž uvádí, že odměnou za vítězství je vyhlášení na webových stránkách IOCCC.

Dějiny

IOCCC zahájili Landon Curt Noll a Larry Bassel v roce 1984, když byli zaměstnáni v portovací skupině Genix společnosti National Semiconductor. Nápad na soutěž přišel poté, co si navzájem porovnali poznámky o nějakém špatně napsaném kódu, který museli opravit, zejména shell Bourne , který pomocí maker emuloval syntaxi ALGOL 68 , a buggy verze prstu pro BSD. Samotná soutěž byla tématem kvízové ​​otázky v roce 1993 Computer Bowl. Po pětileté přestávce počínaje rokem 2006 se soutěž vrátila v roce 2011.

Ve srovnání s jinými soutěžemi v programování je IOCCC Michael Swaine , redaktor časopisu Dr. Dobb, popsán jako „ne tak vážný“ .

Pravidla

Každý rok jsou pravidla soutěže zveřejněna na webových stránkách IOCCC. Veškerý materiál je publikován pod licencí Creative Commons BY-SA 3.0 Unported. Pravidla se rok od roku liší a jsou zveřejněna se sadou pokynů, které se pokoušejí zprostředkovat ducha pravidel.

Hackování pravidel soutěže je tradicí. - Landon Curt Noll, 2011

Pravidla jsou často záměrně psána s mezerami, které soutěžící vybízejí k nalezení a zneužití. Příspěvky, které využívají mezer, mohou způsobit úpravu pravidel pro soutěž následujícího roku.

Použité zmatky

Záznamy často využívají podivné nebo neobvyklé triky, jako je použití preprocesoru C k činnostem, ke kterým nebyl určen (v některých případech „velkolepě“, podle Dr. Dobbse , přičemž jeden záznam vytváří 11bitovou ALU v preprocesoru C ), nebo vyhýbání se běžně používaným konstruktům v programovacím jazyce C ve prospěch mnohem obskurnějších způsobů, jak dosáhnout stejné věci.

Příspěvky zahrnovaly zdrojový kód formátovaný tak, aby se podobal obrázkům, textu atd., Podle způsobu umění ASCII , předefinice preprocesoru, aby byl kód hůře čitelný, a samoopravný kód . Za několik let byl předložen záznam, který vyžadoval novou definici některých pravidel pro příští rok. To je považováno za vysoké vyznamenání. Příkladem je nejkratší samoreprodukční program na světě . Položka byla programem navrženým pro výstup vlastního zdrojového kódu a který měl nulové bajty zdrojového kódu. Když program běžel, vytiskl nula bajtů, což odpovídá jeho zdrojovému kódu.

Ve snaze vyvést zmatek do extrémů vytvořili soutěžící programy, které obepínají okraje standardů C, nebo vedou k konstruktům, které v kompilátorech spouští zřídka používané kombinace cest kódu. V důsledku toho se několik minulých položek nemusí kompilovat přímo v moderním kompilátoru a některé mohou způsobit selhání.

Příklady

V rámci limitu velikosti kódu jen několika kilobajtů se soutěžícím podařilo složité věci - vítěz roku 2004 ukázal operační systém.

Toledo Nanochess

Toledo Nanochess je šachový engine vyvinutý mexickým Oskarem Toledem Gutiérrezem, pětinásobným vítězem IOCCC. V souladu s pravidly IOCCC má délku 1255 znaků. Autor tvrdí, že je to nejmenší šachový program na světě napsaný v C.

Zdrojový kód pro Toledo Nanochess a další motory je k dispozici. Protože Toledo Nanochess vychází z vítězného příspěvku Toleda z 18. IOCCC (nejlepší hra), je silně zmatený .

2. února 2014 vydal autor knihu Toledo Nanochess: Komentovaný zdrojový kód , která obsahuje plně komentovaný zdrojový kód.

Jak 7. února 2010, to vypadá, že je jedním z pouhých dvou šachových motorů napsaných v méně než 2 kilobajtech C, které jsou schopné hrát plné legální šachové tahy, spolu s Micro-Max holandským fyzikem HG Mullerem. V roce 2014 byla bariéra 1 kilobyte prolomena Super Micro Chess -derivátem Micro-Max-celkem 760 znaků (včetně mezer a nových řádků). K dispozici je také menší verze motoru Toledo , Toledo Picochess , skládající se z 944 neprázdných znaků.

Výňatek ze zdrojového kódu

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

Níže je záznam z roku 1988, který vypočítává při pohledu na jeho vlastní oblast :

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

(Tato položka byla napsána v K&R C ; v ANSI C bez některých změn nefunguje správně.)

Letecký simulátor

Dalším příkladem je následující letecký simulátor, vítěz IOCCC z roku 1998, jak je uvedeno a popsáno v části Vypočítané sázky: počítače, hazardní hry a matematické modelování k vítězství (2001) a níže:

#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); } }
Pittsburghská scenérie simulátoru letu

Tento program potřebuje ke kompilaci následující příkazový řádek v systému Linux:

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

Aby bylo možné spustit binární soubor ( banks), musí být dodán se .scsouborem scenérie prostřednictvím stdinvstupu:

 cat pittsburgh.sc | ./banks

Akari

Níže je záznam z roku 2011, který převzorkuje obrázek ascii od 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^*/        ;}

Pokud je program spuštěn pomocí vlastního zdroje jako vstupu, výsledkem je:

[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 ~]#

Viz také

Poznámky a reference

  1. ^ Palmer, Geoff (01.11.2004). „Za příkazovým řádkem“ . PC svět Nový Zéland . Archivovány od originálu 10. února 2013 . Citováno 2013-04-07 .
  2. ^ „Předchozí vítězové IOCCC“ . IOCCC. 2014. Archivováno od originálu dne 2013-12-23 . Citováno 2014-01-08 .
  3. ^ a b c „Pokyny pro rok 2015“ (prostý text) . IOCCC. 2015 . Citováno 2015-11-20 .
  4. ^ "FAQ" . IOCCC . Citováno 2011-11-12 .
  5. ^ "Top Execs se nepodařilo vypočítat správně" . San Jose Mercury News , Kalifornie. 15. května 1993. s. 1A. Prostřednictvím Newsbank . (vyžadováno předplatné)
  6. ^ a b Jackson, Joab (15. listopadu 2011). „Vrácení soutěže o zmatený kód“ . PC svět . Citováno 2013-04-07 .
  7. ^ Swaine, Michael (1. května 2008). „Musí existovat soutěž“ . Dr. Dobb's Journal . Citováno 2013-04-07 .
  8. ^ Domovská stránka IOCCC, zápatí a v každém souboru hint.txt
  9. ^ Spinellis, Diomidis (5. října 2006). „Code Finessing“ . Dr. Dobb's Journal . Citováno 2013-04-07 .
  10. ^ IOCCC 2004 - Nejlepší zneužití CPP IOCCC. Citováno 2013-04-08.
  11. ^ "smr.hint" (prostý text) . IOCCC. 1994 . Citováno 2006-09-16 .
  12. ^ "gavin.hint3" (prostý text) . IOCCC. 2004 . Citováno 2007-03-01 .
  13. ^ Toledo Nanochess a Toledo Picochess
  14. ^ Kdo vyhrál 18. IOCCC
  15. ^ Nanochess částečně de-zmatená verze
  16. ^ Toledo Gutiérrez, Oscar (2014). Toledo Nanochess: Komentovaný zdrojový kód . Lulu . ISBN 978-1-304-86437-6.
  17. ^ http://smmax.sourceforge.net/
  18. ^ Super Micro FIDE 760
  19. ^ "westley.c" , 5. mezinárodní soutěžzmatenýchkódů C 1988, archivováno 2013-10-22 na Wayback Machine. ) IOCCC.
  20. ^ pomocí gcc zkompilovat pomocí následujícího příkazového řádku:gcc -traditional-cpp -o r r.cnebogcc -E r.c | sed 's/- -/--/g' > r2.c ; gcc -o r2 r2.c(zdrojový soubor jer.c)
  21. ^ a b c Letový simulátor IOCCC . aerojockey.com. Citováno 2013-04-08.
  22. ^ Skiena, Steven (2001). Vypočítané sázky: počítače, hazardní hry a matematické modelování na výhru . Matematická asociace Ameriky. s.  152 , 153. ISBN 978-0521009621.
  23. ^ "Index /2011 /akari" . www.ioccc.org . Citováno 2020-09-18 .

externí odkazy