Twenty Eighth International Obfuscated C Code Contest

Aug 3, 2025 - 06:15
 0  0

Twenty Eighth International Obfuscated C Code Contest

Where to start

See below for links to the 2024 winning IOCCC entries.

Check out the index.html web pages for each winning entry. They have most of the information you need to compile and run the winning program. Take a look at the winning source code and try to figure out how it works. You might also want to check out the author’s remarks for even more details.

You may download all winning entries in the form of a compressed tarball, for this year’s contest.

General remarks on this contest

This year marked the 40th anniversary of the IOCCC. The IOCCC28 opened submissions from 2025-03-05 23:19:17.131107 UTC to 2025-06-05 04:03:02.010099 UTC after a 4 year pause.

A significant portion of those 4 years was an effort by a number of people, with over 6168+ commits, to rebuild the Official IOCCC website in what became known as the Great Fork Merge.

Another portion of those 4 years went into retooling the IOCCC, including the creation of the mkiocccentry toolkit, a new IOCCC registration process, and a new IOCCC submit server (which may not be up if the contest is closed).

The major motivation for the above was to:

  • Present IOCCC winners that that honors the contributions of all of the winning authors from around the world,

  • Reduce the administrative effort required by the IOCCC Judges to run the contest, and

  • Minimize the time between when the winners of the IOCCC are selected and when the source is made available.

On the last point, for IOCCC28 the Judging started on 2025-06-05 04:03:02.010099 UTC and then the winners were selected by the IOCCC Judges on 2025-07-07 20:05:07.000000 UTC:

No longer will there be many months between when the winners are announced and their source code is made available. For IOCCC28 the time was less than 2 hours. :-)

Increased submission quantity and quality

The submissions to IOCCC28 were remarkable when compared with previous contests, in both the increased quantity and quality of the submissions. As a result the judging process for IOCCC28 was more challenging and required greater effort. Thankfully due to the above mentioned improvements, the judging process took only 33 days. Under the previous system it would have taken much longer!

One thing that began to emerge after we exits the early rounds of judging and entered the middle rounds of judging was that we were very likely to have more winning entries than in previous contests. Even so, the final rounds of judging required more rounds and tool longer than in any previous IOCCC.

At the end of the final round of the final rounds of judging, we had a record 23 winners of IOCCC28, eclipsing the record of 15 winners!

While we suspect that the 4 year gap between IOCCC27 and IOCCC28 allowed people extra time to improve their submissions, we also believe that people submitting to the IOCCC have adept in obfuscation and have become more skilled in the programming in the C language.

Code size and Rule 2

We were pleased to observe that while the IOCCC size limit increased by about 21%, we received many submissions that were well under the new Rule 2 size limit including a fair number of quality small and medium sized submissions. Half of the IOCCC28 winners were less than 2/3 of the size limit, and 10 of the IOCCC28 winners were less than 1/2 of the size limit!

IMPORTANT NOTE: The IOCCC size limit increase for IOCCC28 was the first size increase in over 10 years. Given the quality of submissions we received that were well under the limit, we do NOT expect to change the Rule 2 size limit for at least another 10 years (and likely longer).

IMPORTANT HINT: Only 3 of 23 the IOCCC28 winners came close to the Rule 2 size limit. Large code size isn’t everything. :-) Those submitting to future contents should take a careful note of that fact.

Rules and Guidelines for this contest

Here are the final versions of the IOCCC rules and guidelines that were in effect for this contest:

Looking forward to the next contest

The IOCCC Judges realize that the IOCCC rules and the IOCCC guidelines need to be greatly improved and streamlined. We decided to not overhaul them for IOCCC28 so as to NOT delay the opening of the contest.

After the IOCCC Judges take a short IOCCC Vacation (we have been working solid on IOCCC28 since 2020 Dec 30), we plan to update, improve and streamline the IOCCC rules and the IOCCC guidelines for IOCCC29. Then we will address whatever bug fixes in the form of GitHub Pull Requests to both the IOCCC GitHub winner repo and the mkiocccentry toolkit repo that may be pending.

Once we are all caught up, we will set the opening date for IOCCC29. It is our plan to open IOCCC29 sometime in 2025 December.

Remarks on some of the winning entries

There were a number of remarkable winning entries for IOCCC28. We wish to call attention to a few of them:

This entry is a fun revisit of the theme of 2000/natori, only better and without using any floating point arithmetic. You are invited to try and understand why the constant 2551443 is common to both entries.

This entry claims to be “the world’s smallest LLM (large language model) inference engine”: running open-source model based on Meta’s LLaMA 2 with 7 billion parameters. After downloading the model via the 2024/cable1/get_model.sh script, we invite you explore this ChatIOCCC tool. While not super fast, the tool’s output can be amusing.

You might wish to ask ChatIOCCC: “Why did this entry win IOCCC28?”?

We encourage you to read and understand the 2024/cable1/prog.c source code. Then see if the ChatIOCCC tool can offer any new, or even correct insights into the code’s obfuscation. :-)

Eh”? The source code, with its UTF-8 conforming accent gives you a polite editor that is more functional an ed(1).

We invite you to use the program to view the UTF-8 fun in the 2024/howe/prog.c source code.

HINT to emacs users: type Q or press CTRL+C to exit. 🤓

When you view the prog.c source code, notice magic numbers. This one liner packs a significant amount of obfuscation in only 135 bytes!

Try giving 10 hex digits to standard input of the program. Then try a different hex digits value. Then feed the MD5 hash of the 2024/stedolan/prog.c source code and “C” what happens. :-)

The 2024/endoh1/try.sh will carry you on a journey that tests your patience as well as the patience of the C-preprocessor.

Building a 8x8 image requires order of 20 seconds of C-preprocessor time, when running 6 jobs on 4 CPU cores in parallel. Unfortunately, with such a tiny image, it is hard to appreciate the image being rendered.

So you might try building a 32x32 form of the image, invoking the C-preprocessor 1024 times. When using 6 jobs on 4 CPU cores in parallel, this might take about 5.5 minutes to complete. However, the small image only gives you a hint of the image being rendered.

If you have the time you might try building a 128x128 image, invoking the C-preprocessor 16384 times. With 6 jobs on 4 CPU cores in parallel, this will take about 1.5 hours. At this scale you might consider it worthwhile to render a more detailed image.

Using 6 jobs on 4 CPU cores in parallel, to build a 512x512 image invoking the C-preprocessor 262144 times over a period of about 23.5 hours, you will be given an image with a reasonable amount of detail to appreciate what is being rendered.

One fun aspect of the 2024/endoh1/prog.c source code is that when it is compiled an executed, the program outputs C code. That C code, call it rt.c will fail to compile! But that is OK because the C-preprocessor has enough work to do without bothering the C compiler. :-)

We plan to recognise those who report that they rendered a new record sized image.

As the expression goes, “Seeing (and hearing) is believing”: or at least can lead to better understanding of the code. :o)

After studying the 2024/weaver/prog.c source code, we suggest you compile and run the program for more information.

This won the “Prize in ℤ₃”, but what does that mean? Well, the “double-struck Z” is NOT a reference to a set of integers, nor is the “double-struck Z subscript 3” a reference to a ring of 3-adic integers. Instead, it is a reference to the 3rd version of a certain virtual machine.

If you use the 2024/mills/try.sh script, you will first be given an opportunity to view the 2024/mills/prog.c source code. Then you will be given 10 choices to play.

HINT: If you select 0: Try to not be eaten by a Grue when reading/navigating the twisty mazes of this source code! :-)

As you study the 2024/codemeow/prog.c source code, try not to lose track of the forest of obfuscation while tracking down the execution path trees.

We think this code will “grow on you” as the C expression goes just a compiled C code “grows on parse trees”. :-)

If seeing is believing, and you believe you understand the 2024/kurdyukov2/prog.c source code, then you might be able to see how the code words.

QUESTION: How many of the “magic numbers” in the program do you understand?

The prize, “virtual quietus”, is a virtual reference to the doom that awaits you when you run this code: let alone when your try to figure out how the author was able to encode the virtual machine in under 2.5K bytes of prog.c source code!

NOTE: The implementation runs without sound or mouse input. You will need reply on your keyboard skills. The 2024/kurdyukov3/try.sh demonstration script will give you some useful keyboard hints.

To those who follow the concept of “seeing is believing” will very likely be “deceived” when they try to see the source in terminal window:

    cat 2024/cable2/prog.c

Viewing the prog.c source code in most editors might suggest that the is something fishy 🐠 with the code.

Have you ever wondered would what would happen if you recursively removed files starting from the root directory? Are you curious what happens when you launch a fork bomb? You can safely give those and other scenarios under this virtual machine.

We invite you to explore the prog.c source code to explore this interesting virtual machine implementation. And as a bonus, a full-fledged C64 emulator is included!

The “Prize in yil-tas” provides a hint as to what this marvelous winning entry is going, provided that you are someone familiar in at least 3 languages (hint: One of them is C, another id English).

The IOCCC is honored to present this entry for your enjoyment and you ponder the prog.c source code.

The IOCCC has seen a number of winning entries that allow code designed to run on early Intel processors, however none of them emulate a processor as early as the Intel 4004. Launched in 1971, the 4004 was the core of the first commercially marketed microprocessor chipset.

The 2024/carlini/prog.c code runs rather slow, so patience is required to watch 4004 code run. This is very understandable when you realize that the 2024/carlini/prog.c is actually emulating the entire 4004 chip circuit by computing the output of each gate in a loop, effectively running the CPU and associated RAM/ROM chips!

Remarks on some of submissions that did not win

  • Depending on the address of a variable, as not all platforms support ASLR, as the single source of pseudo-randomness isn’t a good idea. It’s much better to mix in other sources of variability (e.g. time, process ID, etc.) so that subsequent runs will behave differently.

  • If a submission’s obfuscation strongly resembles a past IOCCC winning entry, and the submission’s obfuscation is mainly in the C code source, then the submission likely to not make it into the final rounds of judging.

  • When working with modern C compilers, it’s crucial to explicitly declare variable and function types. Don’t assume they’ll automatically default to an int.

  • Sadly, K&C-style C code does not compile well under modern C compilers.

  • A submission that only works under gcc or clang does not work as well as submissions that can work under either compiler.

  • Shrinking an existing open-source program to meet rule 2 size might be an impressive feat of code shrinking, but it might not be enough to make it into the final rounds of judging. Originality is key, and this might not be the most innovative approach.

  • If your submission relies on mathematical algorithms, be sure that the C code that implements the mathematics is well obfuscated.

  • Just a friendly reminder that before you upload your submissions, uncompress the compressed tarball into a different directory. This way, you can be sure you didn’t miss uploading any important files!

  • Using a lot of goto statements to make your code harder to understand might not help it pass the final rounds of judging.

Encouragement for those who did not win this year

We know many of you that submitted to the IOCCC put in a ton of effort into your submissions for this year’s IOCCC. We can’t just give out awards to everyone. That would mean taking away from the submissions that we think are the best and deserve to win.

Sometimes, a final round submission might be good enough to be a winning IOCCC entry, only to be beaten by a similar, but slightly better submission. If you think this happened with your submission, consider submitting an enhanced version to the next IOCCC.

PLEASE DO NOT give up hope! There are some submissions that have been submitted with revisions, multiple times before rising to the level of a winning IOCCC entry. You might also want to try with a different type of submission altogether for the next IOCCC.

If you’re not planning to improve and resubmit your non-winning entry for the next IOCCC, you’re welcome to publish it.

On Compiling and running winning entries

Some C compilers aren’t as great as they could be. If yours isn’t working well, you might want to try compiling with an updated version of clang and/or gcc instead.

If you encounter problems in compiling and/or running the winning entries, see the FAQ on:

For additional information on how to submit fixes, see the FAQ on:

For even more information

Winning Entries of 2024 - The 28th IOCCC

Download all winning entries from 2024


Jump to: top

What's Your Reaction?

Like Like 0
Dislike Dislike 0
Love Love 0
Funny Funny 0
Angry Angry 0
Sad Sad 0
Wow Wow 0