Beefy Boxes and Bandwidth Generously Provided by pair Networks httptech
laziness, impatience, and hubris
 
PerlMonks  

camel code

by Erudil (Prior)
on Dec 06, 2000 at 17:41 UTC ( #45213=obfuscated: print w/ replies, xml ) Need Help??

#!/usr/bin/perl -w # camel code use strict; $_='ev al("seek\040D ATA,0, 0;");foreach(1..3) {<DATA>;}my @camel1hump;my$camel; my$Camel ;while( <DATA>){$_=sprintf("%-6 9s",$_);my@dromedary 1=split(//);if(defined($ _=<DATA>)){@camel1hum p=split(//);}while(@dromeda ry1){my$camel1hump=0 ;my$CAMEL=3;if(defined($_=shif t(@dromedary1 ))&&/\S/){$camel1hump+=1<<$CAMEL;} $CAMEL--;if(d efined($_=shift(@dromedary1))&&/\S/){ $camel1hump+=1 <<$CAMEL;}$CAMEL--;if(defined($_=shift( @camel1hump))&&/\S/){$camel1hump+=1<<$CAMEL;}$CAMEL--;if( defined($_=shift(@camel1hump))&&/\S/){$camel1hump+=1<<$CAME L;;}$camel.=(split(//,"\040..m`{/J\047\134}L^7FX"))[$camel1h ump];}$camel.="\n";}@camel1hump=split(/\n/,$camel);foreach(@ camel1hump){chomp;$Camel=$_;y/LJF7\173\175`\047/\061\062\063\ 064\065\066\067\070/;y/12345678/JL7F\175\173\047`/;$_=reverse; print"$_\040$Camel\n";}foreach(@camel1hump){chomp;$Camel=$_;y /LJF7\173\175`\047/12345678/;y/12345678/JL7F\175\173\0 47`/; $_=reverse;print"\040$_$Camel\n";}';;s/\s*//g;;eval; eval ("seek\040DATA,0,0;");undef$/;$_=<DATA>;s/\s*//g;( );;s ;^.*_;;;map{eval"print\"$_\"";}/.{4}/g; __DATA__ \124 \1 50\145\040\165\163\145\040\157\1 46\040\1 41\0 40\143\141 \155\145\1 54\040\1 51\155\ 141 \147\145\0 40\151\156 \040\141 \163\16 3\ 157\143\ 151\141\16 4\151\1 57\156 \040\167 \151\164\1 50\040\ 120\1 45\162\ 154\040\15 1\163\ 040\14 1\040\1 64\162\1 41\144 \145\ 155\14 1\162\ 153\04 0\157 \146\ 040\11 7\047\ 122\1 45\15 1\154\1 54\171 \040 \046\ 012\101\16 3\16 3\15 7\143\15 1\14 1\16 4\145\163 \054 \040 \111\156\14 3\056 \040\ 125\163\145\14 4\040\ 167\1 51\164\1 50\0 40\160\ 145\162 \155\151 \163\163 \151\1 57\156\056

Comment on camel code
Download Code
Re: camel code
by Adam (Vicar) on Dec 06, 2000 at 22:01 UTC
    The master strikes again! ++Erudil
Re: camel code (SPOILERS!)
by jima (Vicar) on Dec 06, 2000 at 22:56 UTC
    And at the risk of spoiling the fun by dissecting the camel, here's my attempt at describing what's going on here, because it's a pretty neat trick, and may encourage other ObWriters to experiment on their own. (People who don't want the fun spoiled should tune out now...)

    The program basically reads its own source code, and prints out a smaller version of the Camel picture, by reducing the image by 50%. It does this by splitting the code up into 2*2 blocks of characters, figuring out which characters in this block are non-whitespace, and printing out a corresponding character to display the picture. Characters range from a " " (for a 4x4 block of spaces) to "X" (for a 4x4 block of non-whitespace).

    The picture is created, stored in an array, and printed out twice (the strings are reversed during the first print, so that the 2nd set of camels are facing the other way). After the picture printout, the O'Reilly disclaimer is printed out.

    Here's my annotated version of the code. Note that, since the formatting has been removed and comments added, this code will not work the same as the original. It's just meant for a study aid.

    #!/usr/bin/perl -w # camel code use strict; $_=' eval("seek\040DATA,0,0;"); # clever way of seeking to beginning + of program file! foreach (1..3) { # skip the first 3 lines (shebang, use str +ict, and a blank line) <DATA>; } my @camel1hump; # variable def's my $camel; my $Camel; # for each line read, grab the following line (if there is another # one to read), and go through the individual characters, detectin +g # whitespace and nonwhitespace characters. # # If you think of the image as being divided into 2x2 character # blocks, then each char in the block will be assigned a power of # 2 thusly: # # +---+---+ # | 8 | 4 | # +---+---+ # | 2 | 1 | # +---+---+ # # For each block, this while block will add up the corresponding # numbers for each nonwhiteapce char, resulting in a number stored # in $camel1hump from 0 to 15. This number will then be translated # to a ASCII picture character from ' ' (for a value of 0, # indicating 4 whitespace characters) to 'X' (for a value of 15, # indicating 4 nonwhitespace chars). These picture chars will be # stored in the string $camel, to be printed out in a fancy way # below. while (<DATA>) { $_ = sprintf("%-69s", $_); # format string in 69 columns my @dromedary1 = split(//); # split $_ into individual char +s if (defined($_ = <DATA>)) { # get next line and split, @camel1hump=split(//); # if it exists } while (@dromedary1) { # for each char my $camel1hump = 0; # this var will hold the bits my $CAMEL = 3; # this var is the bit # if (defined($_ = shift(@dromedary1)) && /\S/) { # if the n +ext char is a nonspace, $camel1hump += 1<<$CAMEL; # add 1<<3 (8) to our + bit counter } $CAMEL--; # next bit... if (defined($_ = shift(@dromedary1)) && /\S/) { # if th +e next char is a nonspace, $camel1hump += 1<<$CAMEL; # add 1<<2 (4) to our + bit counter } $CAMEL--; # next bit... if(defined($_=shift(@camel1hump)) && /\S/) { # if the n +ext char is a nonspace, $camel1hump += 1<<$CAMEL; # add 1<<1 (2) to our + bit counter } $CAMEL--; # next bit... if(defined($_ = shift(@camel1hump)) && /\S/) { # if the + next char is a nonspace, $camel1hump+=1<<$CAMEL; # add 1<<0 (1) to o +ur bit counter ; } # pick out the proper corresponding text format char for t +he # added-up bits. This could be non-obfuscated as a substr( +) # call. $camel .= (split(//,"\040..m`{/J\047\134}L^7FX"))[$camel1h +ump]; } $camel .= "\n"; } @camel1hump = split(/\n/,$camel); # split the picture into indi +vidual lines # Now we print the picture out. The same block of code is included # twice in the program. The reason the second set of cames is reve +rsed # is because the reverse() function call actually does reverse the + # string in the @camel1hump array, so the second time the strings +are # printed, we get a flipped picture. foreach (@camel1hump) { chomp; $Camel=$_; # a bit of obfuscation which just translates 8 of the formatti +ng chars # to the digits "1" through "8", and then back again. y/LJF7\173\175`\047/\061\062\063\064\065\066\067\070/; y/12345678/JL7F\175\173\047`/; $_=reverse; # reverse the string in $_ (which reverses +it in the @camel1hump array) print"$_\040$Camel\n"; # and print out reversed string, alo +ng with the $Camel copy. } # and do basically the same thing again. Since the strings were re +versed in the preceding # block, they're printed out as flipped images of the camel. foreach (@camel1hump) { chomp; $Camel=$_; y/LJF7\173\175`\047/12345678/; y/12345678/JL7F\175\173\0 47`/; $_=reverse; print "\040$_$Camel\n"; } '; # and that's the end of $_. Whew. ; s/\s*//g; # remove all spacing from $_ ; eval; # display the camels eval("seek\040DATA,0,0;"); # seek back to the beginning of program undef$/; $_=<DATA>; # slurp in all the program into $_ s/\s*//g; # remove space ( ); ; s;^.*_;;; # remove all characters until the final "_", which will b +e the last underscore in "__DATA__" # Now print out the O'Reilly disclaimer. The chars in __DATA__ # are just the ASCII values, coded in octal. (And you thought # the picture data was there!) map { # this map statement eval "print\"$_\""; # prints out each octal character } # that it finds /.{4}/g; # using this pattern match. __DATA__ \124\150\145\040\165\163\145\040\157\146 \040\141\040\143\141\155\145\154\040\151 \155\141\147\145\040\151\156\040\141\163 \163\157\143\151\141\164\151\157\156\040 \167\151\164\150\040\120\145\162\154\040 \151\163\040\141\040\164\162\141\144\145 \155\141\162\153\040\157\146\040\117\047 \122\145\151\154\154\171\040\046\012\101 \163\163\157\143\151\141\164\145\163\054 \040\111\156\143\056\040\125\163\145\144 \040\167\151\164\150\040\160\145\162\155 \151\163\163\151\157\156\056
    Whew. Is it lunchtime yet?

    Update: Thanks to Erudil for pointing out that the y/// lines, which I thought were purely for obfuscatory (ooh!) purposes, actually serve a purpose. Namely, to translate non-symmetrical characters to their mirror image. "L" and "J" are exchanged, "F" and "7" are exchanged, etc. (Take a close look at the ordering of the characters in those two y/// lines.)

    As an example of why this needs to be done, look at the camels' heads:
    
      .mm.           .mm.
     .XXX^XLmm   mmJX^XXX.
    .XXXXXXXXXX XXXXXXXXXX.
    {XXXXXX^^^' `^^^XXXXXX}
     XXXXXXL       JXXXXXX
    
    
    See those "L"s and "J"s? If they hadn't been switched with the y/// code, the picture wouldn't have the dark portions in the right areas, and the picture wouldn't be a mirror image:
    
      .mm.           .mm.
     .XXX^XLmm   mmLX^XXX.
    .XXXXXXXXXX XXXXXXXXXX.
    {XXXXXX^^^' `^^^XXXXXX}
     XXXXXXL       LXXXXXX
      ++s all around. And kudos to you for interpreting the obfuscated code for those perl { not so experts } of us around here! =]

      -marius
      jima:

      Nice analysis... But I'd suggest you use the <spoiler> and </spoiler> tags to make it a bit simpler to avoid the spoilers...

      ...roboticus
Re: camel code
by r.joseph (Hermit) on Dec 07, 2000 at 04:20 UTC
    This is absolutely awesome. I printed this out just to put on my wall because, like the penguin poster at ThinkGeek (the poster of the kernel source), code REALLY CAN be art. Not only is this an awesome program, but it looks great next to my camel book :-). Amazing job, and thanks for allowing me to prove to everyone who disbelieves that programming IS art :-). R.Joseph
Re: camel code
by myocom (Deacon) on Dec 07, 2000 at 04:31 UTC
    Hee. A minor note: Running 'perl' and just pasting this in (which I do for many obfuscations) doesn't work so well, thanks to the seeks, I suspect.
Blinded by the light...
by MeowChow (Vicar) on Dec 07, 2000 at 10:50 UTC
    Looking at this camel code has a really odd and disturbing effect on my vision. After I take my eyes out of focus to view the camel, I find that for the next minute, I have a very hard time reading any text on my monitor, as text keeps going in and out of focus.

    It's better now, but when I started writing this, I could barely discern what I was typing and there was even a moment when I thought there might be something wrong with my monitor.

    Try looking at the camel as you would a 3D-stereogram. It it just me?

    ps. amazing code, Erudil

      "Try looking at the camel as you would a 3D-stereogram. It it just me?"

      I think you just gave me the coolest obf idea ever...

        A badge for extreme cleverness goes to Erudil.

         

        To jbeninger:

        If I get your gist your thinking of forming a stereoscopic picture from source code? Cool, but can I advise a lie down in a dark room for a few hours.

        This could be construed as a challenge, but it would be phenomenal to see that even attempted. I'm sure it could be done but every character will need to be right to produce the desired effect, or it would need to be BIG - and stand well back.

        Good luck with it.

Re: camel code
by mrmick (Curate) on Dec 07, 2000 at 19:57 UTC
    Wonderful!!

    Just thinking... wouldn't this make a great t-shirt?

    I'm going to print this off and show it to a couple of colleagues here. Maybe that'll get them more into Perl.

    Very imaginative!

    Cheers,
    Mick

    Mick
      A T-Shirt is actually a good idea. Code on front, output of code on back. If Perlmonks produced the shirt, I'd definitly spend money on it. (Are you listening, vroom? :)

      -Ted
        He might not have been listening, but ThinkGeek was! Note the shirt version is slightly different; Erudil was even able to include a short comment. (Perhaps a new category should now be added to the Perl geek code: "My code has been used on a T-shirt".)
Re: camel code
by ZX (Novice) on Dec 31, 2000 at 03:33 UTC
    this is some very cool obfuscated code! ++Erudil!
Re: camel code
by spacewarp (Pilgrim) on Apr 07, 2001 at 02:49 UTC
    I'm still relatively new to obfuscated programming, so I just have to wonder.. How long did this take to write??

    Spacewarp

    DISCLAIMER:
    Use of this advanced computing technology does not imply an endorsement
    of Western industrial civilization.
Re: camel code
by princepawn (Parson) on May 22, 2001 at 00:40 UTC
    We can all make Camel code now, thanks to Smirch
      Few words to repeat the obvious thing : it's REALLY an amazing obfuscation...
      Thanks to such code, my willingness to learn Perl keeps increasing :)

      Arnaud
Re: camel code
by demerphq (Chancellor) on Jul 07, 2004 at 20:13 UTC

    Ah, just so you know this throws loads of warnings under 5.8.5 RC1 :

    Newline in left-justified string for sprintf at (eval 1) line 1, <DATA +> line 4. ...

    :-)


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


      Just change the shebang line.

      Change the -w to a -X (the warnings will no longer be displayed):

      #!/usr/bin/perl -X              #camel code

        IIRC this silly warning has been removed from Perl in a later version (thank god).


        ---
        demerphq

          First they ignore you, then they laugh at you, then they fight you, then you win.
          -- Gandhi

          Flux8


Re: camel code
by Anonymous Monk on Dec 07, 2004 at 05:46 UTC
    You are the master... I dont know how you got this good... but I'm chassing after you... :)
Re: camel code
by Anonymous Monk on Feb 12, 2012 at 18:53 UTC

    Dear Sir, I am replying from Italy

    I am interested to this image as the possible cover image for a book I will publish within few months.

    I like it because it abstractly expresses some of the basic issues of the book, a book about education and professional formation.

    I wonder if you would give me the authorization to use such image for my cover, mentioning the source, naturally, and promising to send you a copy of the book, if you want, as soon as published (even if, being written in italian, it could be not so interesting for you).

    thanks a lot

    Maurizio Bonfanti

    mail maurizio.bonfanti@fastwebnet.it

      IIRC, O'Reilly registered the trademark of the Camel as a symbol for Perl.

      So you will need to ask them, too.

      Cheers Rolf

      ) That's why the Perl Foundation uses the Onion.

      Erudil hasn't logged in for three years, so you are unlikely to get a reply from him if this is the only means of contact you have tried.

      Regards,

      John Davies

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: obfuscated [id://45213]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (10)
As of 2014-04-23 09:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (541 votes), past polls