[HN Gopher] Twenty Eighth International Obfuscated C Code Contest
___________________________________________________________________
Twenty Eighth International Obfuscated C Code Contest
Author : mdl_principle
Score : 301 points
Date : 2025-08-03 04:34 UTC (18 hours ago)
(HTM) web link (www.ioccc.org)
(TXT) w3m dump (www.ioccc.org)
| _kb wrote:
| For an obfuscation comp, I love the fact they explicitly refer to
| and do not rewrite "index.html web pages for each winning entry".
| 4pkjai wrote:
| As a noob, this is confusing me.
| rawling wrote:
| Usually web servers can be configured so if you request a
| directory it will look in that directory for index.html and
| serve it if it finds it.
|
| This page explicitly links to name/index.html for each
| submission rather than just name, an ironic waste of bytes
| given the subject matter.
| bcardarella wrote:
| > Increased submission quantity and quality
|
| So everybody just LLM'd this, right?
| mattigames wrote:
| Vibe obfuscation, all the cool kids are doing it.
| w-ll wrote:
| i guess that _should_ make vibe de-obfuscation as easy
| Disposal8433 wrote:
| That would be the Underhanded C Contest
| (https://en.wikipedia.org/wiki/Underhanded_C_Contest)
| s-macke wrote:
| LLMs can help you analyze the code, but not write it. Their
| ability to obfuscate is quite limited and uninspired. The last
| IOCCC was in 2020, so we've had plenty of time to work on it.
| dyauspitr wrote:
| What do you mean by an LLM can't write it?
| Sharlin wrote:
| That they're bad at the exact thing this competition is
| about: writing clever obfuscated code.
| anonzzzies wrote:
| I would go further and say the fine tuning on code,
| mostly by llms generating for other llms and human sweat
| shops writing example code to train on is actually to
| teach the llms the opposite of clever code and obfuscated
| code. Llms try to create readable, documented code (with
| different levels of success). When I make them generate
| terse/obfuscated code, they cannot help themselves by
| putting too much readable things in there. I asked claude
| to do the moon phase one and it had the calculation
| correctn but could not figure out how to draw the ascii
| moon so it just printed the values, used emojis next to
| the ascii etc. But when you ask to do it with normal
| code, it does figure it out.
| Xant42 wrote:
| Hello. I can confirm being the person that produced the
| shows live event and graphics and whatnot that I had a
| chance to see if any of the llms available could
| understand the code and beyond some very superficial
| stuff they more or less completely failed to understand
| any of the entries this year. Hope you enjoyed the
| presentation. There will be more to come in the out
| favorite universe channel in the future that should be
| fun.
| AlotOfReading wrote:
| I didn't find them useful when I wrote my entries. LLMs get
| confused with code that "looks like" other code, and that
| intentional misdirection is half the fun of a good IOCCC entry.
| Plus, the morality filters get annoying once you obfuscate the
| code. Plugging an unsubmitted entry into Gemini, it refuses to
| even explain it because it thinks it's malware.
| rjh29 wrote:
| A four year gap since the last contest would explain both of
| those.
| Sharlin wrote:
| Quantity? _Maybe_. Quality? _Extremely_ doubtful. But both are
| much more likely to be simply due to the four-year break.
| nurettin wrote:
| They said increased quality.
| andrepd wrote:
| > Increased quality
|
| I think you can answer your own question
| isoprophlex wrote:
| https://www.ioccc.org/2024/stedolan/index.html
|
| Reading last years entries, this image decompression oneliner
| outputs its own logo when passed the hash of its source code?!
| Pretty neat.
| jama211 wrote:
| Yeah I just read that one, insane!
| alexey-salmin wrote:
| The guy obviously enjoys obscure piping commands, the other
| one being jq
| weinzierl wrote:
| I was wondering how the hash thing worked. Got my answer from
| the notes, which are otherwise hilarious.
|
| _" While terseness was preferred over obscurity, this program
| hopefully still lives down to IOCCC's usual standards of
| clarity."_
| Someone wrote:
| Also:
|
| _"Several variants of this program were considered.
| Several."_
|
| (They must have tried billions of variants to find the match
| on _md5sum_. Luckily, you don't have to compile or run the
| code to find that match)
| codethief wrote:
| Indeed!
|
| > By an astonishing coincidence, the number of bits in the
| input format is approximately the log2 of the number of MD5
| evaluations that a five-year-old GPU can do in an hour.
| bspammer wrote:
| I still don't understand how it works, the source code
| doesn't have any obvious sections to insert data for brute-
| forcing. I'm as confused as the judges:
|
| > There are no magic numbers in the program, and bits of the
| input map to pixels of the output in a regular way, yet it
| outputs a nice icon for itself, if given the MD5 hash of its
| own source. How?
|
| I'm assuming the fact that MD5 is completely broken plays
| into it somehow...
| 0points wrote:
| > By an astonishing coincidence, the number of bits in the
| input format is approximately the log2 of the number of MD5
| evaluations that a five-year-old GPU can do in an hour.
|
| I read this to mean he calculated a matching hash on his
| GPU, in order to tune the magic constants of his app to
| produce the desired output.
|
| > There are no magic numbers in the program
|
| There are several: long
| z,x,G;main(){for(puts("P1\n80 80"),scanf("%10lx",&G);3-z/21
| 60;x=++z%81/8-5)putchar(5>x?!(16>>(x^-(x<1))+1&G<<5>>z/648*
| 5)^49:10);}
| bspammer wrote:
| Most of those numbers aren't possible to change, 80x80 is
| the output size, %10 is the input size.
|
| Changing any of the other numbers would surely impact the
| function of the program, I don't think you could get to a
| 40 bit brute-force there.
|
| I think the brute-force was done by making non-semantic
| changes like variable names and changing the order of the
| declarations.
| addaon wrote:
| > I think the brute-force was done by making non-semantic
| changes like variable names and changing the order of the
| declarations.
|
| Yep. You have 17 bits of entropy just in the names of
| three single-letter variables.
| bspammer wrote:
| Thinking about it more, I guess you can just change the
| single-letter variable names and positioning to quite
| easily get up to a 40 bit brute-force.
| abcd_f wrote:
| In 135 bytes !
|
| This is right there in the mad scientist territory.
|
| Incredible, pure bananas.
| s_dev wrote:
| Same guy wrote jq
| ForOldHack wrote:
| Thank you Barry Kerchival, My C programming teacher for sharing
| obfuscated code, and showing us utter abuse of the C pre-
| processor. "This does not do what you think it does."
|
| "Recalcitrant code."
| 01HNNWZ0MV43FF wrote:
| "You could hide a semi truck in 200 lines of C"
| ForOldHack wrote:
| At the beginning of the semester, we had a question about
| struct... Armed with the error code,she showed it to Barry.
| He looked at it, sat down at her machine, and typed a few
| lines. Compiled it, put the disks for the compiler back in
| the folder, put the folder and the manual in the box and
| threw it against the wall above the garbage can, and it
| landed for a two-pointer. "We will have a new compiler on
| Monday."
|
| Thus ended the use of Lattus-C, and Microsoft-C for a least 4
| years. We went with Manx-C, and were able to complete all the
| assignments for that semester.
|
| He saved the best for later. "Read 'on trusting trust'" which
| blew all out minds.
|
| You can hide whole universes inside of a C compiler.
| dbacar wrote:
| This is epic: :)
|
| From : https://github.com/ioccc-
| src/winner/blob/master/2024/kurdyuk...
|
| This code draws the current moon phase to the console. So if
| you're a lycanthrope, you can monitor the phase of the moon.
|
| #include <time.h> #include <stdio.h>
| a,b=44,x, y,z;main() {!a ?a=2551443,x= -b
| ,y=2-b,z=((time ( 0)-592531)%a<<9)/ a
| :putchar(++x>=a?x = -b,y+=4,10:x<0?x= x
| *x+y*y<b*b?a=1-x, - 1:x+1,32:"#."[( x
| <a*(~z&255)>> 8) ^z>>8]),y> b?0
| :main();}
| _kb wrote:
| That's a bit of a hat tip to donut.c:
| https://www.a1k0n.net/2011/07/20/donut-math.html
| dbacar wrote:
| I didnt know that, thanks.
| pelagicAustral wrote:
| This is the exact type of thing that makes me feel like I am
| in the wrong line of business...
| ycuser2 wrote:
| The donut is kind of cheated because it uses comments.
| omoikane wrote:
| Probably more of a hat tip to this one:
|
| https://www.ioccc.org/2000/natori/index.html
|
| https://github.com/ioccc-
| src/winner/blob/master/2000/natori/...
|
| It's interesting how the same 2551443 bitmask appears in the
| time calculation for both.
| repmop wrote:
| 2551443 is the length of the synodic month in seconds. The
| calculation being done converts the current time in seconds
| into a 512-wide integer range representing the lunar phase
| by offsetting from the lunar phase during the unix epoch.
| rwmj wrote:
| Slightly reminiscent of a 1988 entry to calculate Pi:
| https://en.wikipedia.org/wiki/International_Obfuscated_C_Cod...
| The 1988 entry uses its own source code to calculate it.
| chuckadams wrote:
| I loved the description that was attached to one version of
| it: "to get more precision, write a bigger program".
| sgt wrote:
| To compile this: cc -Wno-implicit-int -Wno-
| implicit-function-declaration phase.c && ./a.out
| wild_pointer wrote:
| Compiler Explorer link: https://c.godbolt.org/z/xE8hzM189
| somat wrote:
| The entry rules are great. Highly specific in that way you know
| exactly how they were abused in the past. Rule
| 2 Rule 2 requires that your submission satisfy
| BOTH Rule 2a AND Rule 2b. You may check your
| code with respect to Rule 2a and Rule 2b prior to
| submitting your code by giving the filename as a command like
| argument to the iocccsize(1) tool. For example:
| iocccsize prog.c The source to iocccsize(1) may be
| found in the mkiocccentry repo. See also the FAQ on
| "how to further test your submission" for more more thorough
| testing, including Rule 2. See also Rule 2a, Rule
| 2b, and Rule 17. Rule 2a The size of
| your program source should NOT exceed 4993 bytes.
| Rule 2b When the filename of your program source is
| given as a command line argument to the latest version of
| the official IOCCC size tool (hereby referred to as
| iocccsize(1)), the value printed should NOT exceed 2503.
| See also Rule 17.
| raverbashing wrote:
| 4993 bytes, I wonder how did they came up with such a specific
| number
| Sharlin wrote:
| So you are allowed to store 2053 bytes worth of extra data in
| the filename. That's... surprisingly lenient.
| GranPC wrote:
| How would you actually read that data back from your program?
| ashdnazg wrote:
| argv[0]
| GranPC wrote:
| That would only work assuming the program isn't just
| compiled to "a.out". I don't think this "loophole" would
| work at all.
|
| edit: Nevermind, I misread the original rule.
| lapsis_beeftech wrote:
| __FILE__
| theletterf wrote:
| Ah, obfuscated code, the mark of a genuinely human developer. :-)
| tiu wrote:
| Can https://www.underhanded-c.org/ also please come back!
| pelagicAustral wrote:
| I wonder what the future of these competitions is in the era of
| AI. Same for the Advent of Code.
| Jaxan wrote:
| Advent of Code is not really a competition. There is a ranking,
| but that's not the point of it.
| pelagicAustral wrote:
| Wouldn't people be competing to be at the top of the ranking?
| I should think that the Real Madrid participates in La Liga
| because they want to win and not just flair their way around.
| AIPedant wrote:
| Advent of Code needs to get rid of that stupid leaderboard
| and display winning entrants' names alphabetically. It's
| not even slightly a fair competition, an entire swath of
| people are out of the running simply because they are too
| tired at 11pm (or busy with their kids etc) to solve a
| little puzzle. I think anyone trying to "compete" in AoC
| needs to reassess their priorities.
|
| Also, I like reading the "flavor text" about the elves and
| whatnot. Encouraging people to ignore it seems at odds with
| the design of AoC.
| recursive wrote:
| It's OK to compete. And it's on not to. You can ignore
| the leader board.
| a_dabbler wrote:
| It's more like a marathon, sure you're in a race but people
| don't really care about your position in it unless you're
| near the front. Completing it on its own gives a feeling of
| achievement
| bashauma wrote:
| these works are really gems, but this type code is very
| strange, and not useful for standard situation. AI devs will
| take more "normal and useful" code for learning their products
| than these "noisy and hard-reading" code.
| VoidWhisperer wrote:
| It would appear that someone forget to add something before
| putting the page up... part way down the page is 'XXX-add-show-
| URL-here-XXX' referring to a youtube livestream vod for the
| announcement of the winners
|
| Edit: Before posting this, I looked to see if there was a
| repository I could contribute to to fix it, but I can't find one
| s-macke wrote:
| Livestream yesterday
|
| https://www.youtube.com/live/UDzGwTalVAc
| delduca wrote:
| My favorite entry (and was a winner)
|
| https://github.com/ioccc-src/winner/blob/master/2005/persano...
| dogman1050 wrote:
| Ah yes, brings to mind a new engineer we hired in the early 90's
| with with an excellent academic record from a fine school
| introducing himself to the team by emailing everyone an
| obfuscated one-liner C program that did something cute. Several
| members of the team responded to him with lists of ways in which
| his program violated our recently create style guide. We were a
| fun group.
| Retr0id wrote:
| Aaaaaaa, I always learn of these after they've happened. I've
| wanted to enter for a long time.
| deater wrote:
| my plan to rick-roll every major coding competition continues
| apace. muahahaha
|
| I actually had another entry that I felt had much more clever
| coding that did some nice sixel animations but from what I
| understand there were many entries also doing that this year
| sgt wrote:
| The question, ladies and gentlemen, that we're all waiting for;
| Just how many of this year's IOCCC entries were vibe coded? /s
| capitainenemo wrote:
| Unfortunate that the redesign broke all links to the old entries
| (which, since they've been around for decades are on quite a few
| sites - wikipedia for example) without redirects, and now
| requires using a javascript capable browser to view the entries
| on github (github having removed non-JS access last year).
| connicpu wrote:
| I guess the JS-free way to access would be `git clone`
| textlapse wrote:
| I wonder if there is an LLM competition that can take the
| obfuscated code and return the unubfuscated/detailed code...
| thepace wrote:
| Claude gave me this unobfuscated C code for `long
| z,x,G;main(){for(puts("P1\n80 80"),scanf("%10lx",&G);3-z/2160;x
| =++z%81/8-5)putchar(5>x?!(16>>(x^-(x<1))+1&G<<5>>z/648
| _5)^49:10);}`:
|
| #include <stdio.h>
|
| /_ * PPM Pattern Generator * * This program generates a 80x80
| black and white PPM image based on a * hexadecimal input
| pattern. The pattern is rendered as ASCII art using * bit
| manipulation to determine which pixels are on or off. _/
|
| int main() { long pixel_index = 0; // Current pixel being
| processed (0-6399 for 80x80) long horizontal_offset; //
| Horizontal position relative to center long hex_pattern; //
| Input hexadecimal pattern // Output PPM
| header for 80x80 black and white image // P1 = ASCII
| black and white format // 80 80 = width and height
| puts("P1\n80 80"); // Read hexadecimal pattern
| from user (up to 10 hex digits) scanf("%10lx",
| &hex_pattern); // Process each pixel in the
| 80x80 image // Continue until we've processed all
| pixels // The condition (3 - pixel_index/2160)
| continues while pixel_index < 6480 // This accounts for
| 80x80 = 6400 pixels plus some margin for (; 3 -
| pixel_index/2160; ) { // Move to next
| pixel and calculate horizontal offset from center
| pixel_index++; horizontal_offset = (pixel_index %
| 81) / 8 - 5; // Determine what to
| output for this pixel if (horizontal_offset < 5) {
| // We're in the main pattern area (central region)
| // Complex bit manipulation to determine pixel state:
| // 1. Calculate bit position based on horizontal offset
| int bit_pos = (horizontal_offset ^ -(horizontal_offset < 1)) +
| 1; // 2. Extract relevant bits
| from the pattern // hex_pattern << 5 shifts the
| pattern // >> (pixel_index/648*5) selects which
| part of pattern to use based on vertical position
| long pattern_bits = (hex_pattern << 5) >> (pixel_index/648 *
| 5); // 3. Check if the
| specific bit is set int bit_is_set = (16 >>
| bit_pos) & pattern_bits; // 4.
| Invert the bit and XOR with '1' (ASCII 49) to get '0' or '1'
| char pixel_char = (!bit_is_set) ^ 49;
| putchar(pixel_char); } else {
| // We're outside the pattern area - output newline
| putchar(10); // ASCII 10 = newline character }
| } return 0;
|
| }
|
| /_ * USAGE: * Compile: gcc -o pattern_gen pattern_gen.c * Run:
| ./pattern_gen * Input: Enter a hexadecimal number (e.g.,
| 1234ABCD) * Output: PPM format image data that can be saved to
| a .pbm file * * EXAMPLE: * ./pattern_gen > output.pbm * Then
| input: DEADBEEF * * The resulting .pbm file can be viewed with
| image viewers that support PPM format * or converted to other
| formats using tools like ImageMagick. */
| maxmcd wrote:
| Was quite confused by this one: https://github.com/ioccc-
| src/winner/blob/master/2024/cable2/...
| 1vuio0pswjnm7 wrote:
| "Sadly, K&C-style C code does not compile well under modern C
| compilers."
|
| What is K&C
|
| Is this a typo
| hencoappel wrote:
| Guessing they meant K&R style C?
| ForOldHack wrote:
| Who is 'C?' Asking for a friend.
| kmoser wrote:
| Ritch-C?
| __turbobrew__ wrote:
| Christ
| bapak wrote:
| You're probably a programmer. This is what your job looks like to
| everyone except programmers. Pure gibberish.
| drmaximus wrote:
| You might also be interested in the Grand C++ Error Explosion
| Competition: https://tgceec.tumblr.com/
| Mvulane wrote:
| Ji
| sureglymop wrote:
| This one is so cool: https://github.com/ioccc-
| src/winner/tree/master/2024/macke
|
| > This is an emulator capable of running a full modern Linux
| system with a minimal set of features.
| s-macke wrote:
| Author here. Yes, it runs a modern Linux from a 1.6MB binary. I
| did everything possible to make it as small as I could. It even
| compiles into WebAssembly and runs in the browser.
| earnestinger wrote:
| I'm stll waiting for the revival of the cousin, underhanded c
| contest.
___________________________________________________________________
(page generated 2025-08-03 23:00 UTC)