|
Narcissistic program challenge
Last post 07-08-2008 10:50 AM by rdrunner. 28 replies.
-
-
-
Lingerance


- Joined on 07-24-2007
- Posts 857
|
Re: Narcissistic program challenge
So basically this is a bizarre reverse-quine? WFT.
irc://irc.slashnet.org/#TDWTF "You acquaint the SURLY THUGS with your brand of diplomacy."
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 191
|
Re: Narcissistic program challenge
// narc.cpp
#include <cstdio>
int main()
{
FILE narc = fopen("narc.cpp", "w+");
for (int ch = getchar(); ch != EOF; ch = getchar())
fputc(ch, narc);
fclose(narc);
puts("1");
return 0;
}
rpar PROTON all
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 191
|
Re: Narcissistic program challenge
I have another solution too, but it involves you not being able to see the source.
rpar PROTON all
|
|
-
-
ComputerForumUser


- Joined on 02-15-2007
- Posts 72
|
Re: Narcissistic program challenge
It's not even so much of a reverse quine - any quine that builds a string of its code can do a comparison between that and the input: <?php $str = '<?php $str = \'X\'; echo substr_replace($str, addslashes($str), 14, 1); ?>'; echo substr_replace($str, addslashes($str), 14, 1); ?>
... becomes ...
<?php $str = '<?php $str = \'O\'; $prog = substr_replace($str, addslashes($str), 14, 1); if (!strcmp($argv[\'input\'], $prog)) echo \'1\'; else echo \'0\'; ?>'; $prog = substr_replace($str, addslashes($str), 14, 1); if (!strcmp($_GET['input'], $prog)) echo '1'; else echo '0'; ?>
Briefcase is Lord!
|
|
-
-
dextron


- Joined on 02-05-2008
- Posts 11
|
Re: Narcissistic program challenge
Here's a Ruby solution....
cmd=<<EOF def do_compare(testFile,cmdString) cmdArr=cmdString.to_a.each {|l| l.chomp!} cmdArr[0,0]= "cmd=<<EOF" cmdArr.push "EOF","eval cmd","do_compare(ARGV[0],cmd)" testArr=File.open(testFile).collect.each {|l| l.chomp!} puts "1" if cmdArr==testArr puts "0" unless cmdArr==testArr end EOF eval cmd do_compare(ARGV[0],cmd)
|
|
-
-
zentar


- Joined on 04-01-2008
- Posts 3
|
Re: Narcissistic program challenge
This is the closest I could come up with, in a bash shell script:
#!/bin/bash
diff $0 $1 1> /dev/null 2>&1
if [ $? -eq 0 ]; then
echo 1
else
echo 0
fi
|
|
-
-
flop


- Joined on 04-27-2007
- Posts 51
|
Re: Narcissistic program challenge
If it must not access its own source code, there are two solutions: Either it accesses a copy of its own source code, or it uses another way to know whether it found it.
Using a CRC32 would have too many false positives, so I settled for MD5 ... but my machine is too slow, I only have 14 of 32 characters matching: b452cdaf2785e22fb69cbb078cbafa80 vs. be32ca183785e22db6cbb52a18b528e0.
#!/bin/sh
CONSTANT=b452cdaf2785e22fb69cbb078cbafa80
if [[ `md5sum < "$1" | cut -f1 -d" "` eq $CONSTANT ]]
then
echo 1
else
echo 0
fi
Please note that an empty line must be included at the end.
|
|
-
-
flop


- Joined on 04-27-2007
- Posts 51
|
Re: Narcissistic program challenge
What I forgot to mention: Yes, I know about hashclash (http://www.win.tue.nl/hashclash/), and yes, I'm hoping for the best.
Just a quick-and-dirty solution (try) ... If I'd replace all but 31 characters in the constant by ? I'd even have a match now. (Still standing at 14.)
|
|
-
-
BeenThere


- Joined on 04-11-2008
- Posts 131
|
Re: Narcissistic program challenge
Here's one in JavaScript. Doesn't access any files, and takes the Script tags into account. or input, just use any old textarea and paste it in, and onclick the value to the function:
<script language='javascript'> function narcissistic(input) { var narcissist = "%3Cscript%20language%3D%27javascript%27%3E%0Afunction%20narcissistic%28input%29%20%7B%0A%09var%20narcissist%20%3D%20%22%22%3B%0A%09var%20narcissist2%20%3D%20narcissist.substr%280%2C119%29+escape%28narcissist%29+narcissist.substr%28119%29%3B%0A%09if%20%28input%20%3D%3D%20unescape%28narcissist2%29%29%20return%20true%3B%0A%09return%20false%3B%0A%7D%0A%3C/script%3E"; var narcissist2 = narcissist.substr(0,119)+escape(narcissist)+narcissist.substr(119); if (input == unescape(narcissist2)) return true; return false; } </script> It's 'sourcecode pattern' var uses the pattern of the primary program without the escaped source put into it (just "" if unescaped), then drops it in programmatically on the next line.
That way it can "know what it looks like when it knows what it looks like" but hell - it works without cheating!
The mind boggles, And yet the goggles, They do nothing.
|
|
-
-
BeenThere


- Joined on 04-11-2008
- Posts 131
|
Re: Narcissistic program challenge
Whole HTML if anyone cares:
<html>
<head>
<script language='javascript'>
function narcissistic(input) {
var narcissist = "%3Cscript%20language%3D%27javascript%27%3E%0Afunction%20narcissistic%28input%29%20%7B%0A%09var%20narcissist%20%3D%20%22%22%3B%0A%09var%20narcissist2%20%3D%20narcissist.substr%280%2C119%29+escape%28narcissist%29+narcissist.substr%28119%29%3B%0A%09if%20%28input%20%3D%3D%20unescape%28narcissist2%29%29%20return%20true%3B%0A%09return%20false%3B%0A%7D%0A%3C/script%3E";
var narcissist2 = narcissist.substr(0,119)+escape(narcissist)+narcissist.substr(119);
if (input == unescape(narcissist2)) return true;
return false;
}
</script>
</head>
<body>
<form name="mainform">
<textarea name="inputdata" cols="400" rows="20" ></textarea><br>
<input type="button"name="btn" value="test" onclick="alert(narcissistic(document.mainform.inputdata.value));">
</form>
</body>
</html>It goes off the page to the right, but will show up if you copy/paste. The program is considered from "<script..." to "...</script>" without the following linebreak.
The mind boggles, And yet the goggles, They do nothing.
|
|
-
-
The Enterpriser


- Joined on 04-30-2008
- Posts 12
|
Re: Narcissistic program challenge
unless I'm mistaken, this isn't much of a challenge right..?
pseudo code:
String programCode = "all the code in this file" ;
if(input.equals(programCode)
return 1;
return 0;
A more enjoyable solution would be to read the program from memory and work from there.. although you would only find out if the logic was the same, not the code itself.
|
|
-
-
ammoQ


- Joined on 04-13-2005
- Vienna.Austria.Europe.Earth
- Posts 3,332
|
Re: Narcissistic program challenge
The Enterpriser:unless I'm mistaken, this isn't much of a challenge right..?
pseudo code:
String programCode = "all the code in this file" ;
if(input.equals(programCode)
return 1;
return 0; I'm not sure whether or not this post is for real, so just in case you really mean it: You will soon find out that the "all the code in this file" part is really hard. Because it's impossible even in pseudocode (linebreaks removed and escaping ommited for clarity):
String programCode = "String programCode = "all the code in this file" ; if(input.equals(programCode)) return 1; return 0;" ;
if(input.equals(programCode))
return 1;
return 0; You can repeat that ad infinitum without getting anywhere.
beanbag girl 4ever
|
|
-
-
The Enterpriser


- Joined on 04-30-2008
- Posts 12
|
Re: Narcissistic program challenge
fair enough, for those of us who are too lazy to type to infinity...
I'd go with the hash solution. Although finding out the hash of the source code where the source code includes said hash, sounds like a fun problem in itself.
|
|
-
-
BeenThere


- Joined on 04-11-2008
- Posts 131
|
Re: Narcissistic program challenge
The Enterpriser:fair enough, for those of us who are too lazy to type to infinity...
I'd go with the hash solution. Although finding out the hash of the source code where the source code includes said hash, sounds like a fun problem in itself.
The only way is to construct the source at runtime out of data that is the source without the "source var" populated. A hash could work if it was reverseable, because you'll need to manipulate the sourcecode var at runtime. I went with escaping the source to a hex string because you can still perform string parsing on the whole variable without corrupting the value.
The mind boggles, And yet the goggles, They do nothing.
|
|
-
-
ammoQ


- Joined on 04-13-2005
- Vienna.Austria.Europe.Earth
- Posts 3,332
|
Re: Narcissistic program challenge
Time to post a really working solution that perfectly matches the challenge... Edit: Oops, I haven't seen until now that BeenThere seems to have solved the challenge, too, one day before me... #include <stdio.h> int main(int argc, char **argv ) { char b[999]; char f[999]; char *s="#include <stdio.h>%cint main(int argc, char **argv ) { char b[999]; char f[999]; char *s=%c%s%c; sprintf(b,s,10,34,s,34,10); fread(f,1,451,stdin); putc(48+(feof(stdin) && !memcmp(f,b,450)),stdout); putc(10,stdout); return 0; }%c"; sprintf(b,s,10,34,s,34,10); fread(f,1,451,stdin); putc(48+(feof(stdin) && !memcmp(f,b,450)),stdout); putc(10,stdout); return 0; }
Runs on Linux, because it depends on LF as line delimiters (as opposed to CR LF on Windows). But you Windows users can easily change that, can you?
[erich@iTux ~]$ ./narcist <narcist.c 1 [erich@iTux ~]$ ls -l narcist.c -rw-r--r-- 1 erich erich 450 Mai 1 19:11 narcist.c [erich@iTux ~]$
Make sure the source is exactly 450 bytes long, no extra linefeeds etc. allowed...
Readable (but non-working b/c of the extra whitespace) version of the source code:
#include <stdio.h> int main(int argc, char **argv ) { char b[999]; char f[999]; char *s="#include <stdio.h>%cint main(int argc, char **argv ) { char b[999]; char f[999]; char *s=%c%s%c; sprintf(b,s,10,34,s,34,10); fread(f,1,451,stdin); putc(48+(feof(stdin) && !memcmp(f,b,450)),stdout); putc(10,stdout); return 0; }%c"; sprintf(b,s,10,34,s,34,10); fread(f,1,451,stdin); putc(48+(feof(stdin) && !memcmp(f,b,450)),stdout); putc(10,stdout); return 0; }
beanbag girl 4ever
|
|
-
-
The Enterpriser


- Joined on 04-30-2008
- Posts 12
|
Re: Narcissistic program challenge
Shameful cheating I know...
open(PROGRAM,">>narc.pl"); $input = $ARGV[0]; $input =~ s/\W//g; print PROGRAM "#" . $input; close PROGRAM; print 0;
|
|
-
-
BeenThere


- Joined on 04-11-2008
- Posts 131
|
Re: Narcissistic program challenge
The Enterpriser:Shameful cheating I know...
open(PROGRAM,">>narc.pl"); $input = $ARGV[0]; $input =~ s/\W//g; print PROGRAM "#" . $input; close PROGRAM; print 0;
You do realize that "cheat" method has been posted several times over in this very thread, right? Basically, that's plagerism off a "fail" which...I can't begin to quite understand...
The mind boggles, And yet the goggles, They do nothing.
|
|
-
-
The Enterpriser


- Joined on 04-30-2008
- Posts 12
|
Re: Narcissistic program challenge
You do realize that "cheat" method has been posted several times over
in this very thread, right? Basically, that's plagerism off a "fail"
which...I can't begin to quite understand...
No, where?
|
|
-
-
omega0


- Joined on 04-26-2007
- Posts 57
|
Re: Narcissistic program challenge
Three perl solutions, they grown scarier (but also cheat more) as you go
print <<'' x 2 . "\n" eq join'',<STDIN>
print <<'' x 2 . "\n" eq join'',<STDIN>
--
use B::Deparse;sub x{ undef $/; print 'use B::Deparse;sub x' . 'B::Deparse'->new->coderef2text(\&x) . "x;\n" eq <STDIN>; }x;
--
#!perl $ENV{PERL5DB}='*DB::DB=sub{}';exec"$^X -d -0777 $0"if!$^P; binmode STDIN;print <STDIN>eq join'',@{"_<$0"}[1..3];
|
|
-
-
omega0


- Joined on 04-26-2007
- Posts 57
|
Re: Narcissistic program challenge
The Enterpriser:I'd go with the hash solution. Although finding out the hash of the source code where the source code includes said hash, sounds like a fun problem in itself. Since you know exactly what the line containing the hash looks like, just keep it out of the hash:
uuse Digest::MD5; $hash = '83b099b39b1679357ceebe2dc394f0ed'; @data = ; $removed = splice @data, 1, 1; $result = Digest::MD5::md5_hex( join "", @data ); print $result eq $hash and $removed eq "\$hash = '$hash';";
|
|
-
-
flop


- Joined on 04-27-2007
- Posts 51
|
Re: Narcissistic program challenge
omega0:Since you know exactly what the line containing the hash looks like, just keep it out of the hash:
Nice trick. But I think you forgot the \\n in the $hash-comparision... and @data seems a bit destroyed, too. "uuse" is good as well ;-)
|
|
-
-
too_many_usernames


- Joined on 12-09-2005
- (0,0,0) in local frame
- Posts 146
|
Re: Narcissistic program challenge
Attempting for worse abuse of the rules: #include <stdio.h> int main(int argc,char**argv) { /* since all inputs which could be passed to this program would be copies, rather than the original code itself, nothing matches. */ return 0; }
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 191
|
Re: Narcissistic program challenge
You could also read in a string, and put a null character somewhere in the source.
rpar PROTON all
|
|
-
-
ammoQ


- Joined on 04-13-2005
- Vienna.Austria.Europe.Earth
- Posts 3,332
|
Re: Narcissistic program challenge
It's actually not that very difficult to solve that challenge. Just take any one of the quine-type self-replicating programs that are available in large numbers, and redirect the output to a buffer that is finally compared against the input. Adjust the quine part, done.
beanbag girl 4ever
|
|
-
|
|