It's very inspired, ruoso! I like your use of closures, but especially turning one string into another ... muito boa ideia!
I'll return your favor, providing a spoiler to your obfuscation, as well as a suggestion for making it 3 lines instead of 6:
#!/usr/bin/perl
+
# Converts 'rootrootrootrootrootroot' into 'just another perl hacker'
# Data contains 48 bytes: first 24-bytes => (0=skip, 1=convert to spa
+ce)
# and last 24-bytes are ascii offsets for character conversions, and i
+s
# iterated twice through.
my @data = qw(
0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0
+ 0 0
8 -6 -4 0 0 14 1 5 -2 7 10 2 0 -1 10 2 6 0 7 19 15 4
+10 2
);
+
my $p_turn_root_into_japh = sub{
my $arg = shift;
for (my $i = 0; $i < @data; $i++) {
my $c = $data[$i];
my $pclosure = sub {
my $p = $_[0];
# Uncomment next line to see string conversion progression
# printf "[$arg]\n";
if ($i > 23) {
# Now convert 1 char at a time from 'rootrootroot...'
# to the target char, by subtracting appropriate ascii
+ val.
# Comment out next line only, and you get:
# "root ootroot ootr otroot"
substr($$p, $i-24, 1) = chr(ord(substr($$p,$i-24,1))-$
+c);
}
if ($c && $i < 24) {
# Comment out next line only, and the end result is:
# "justranotherrperlohacker"
substr($$p,$i,1) = ' ';
}
};
$pclosure->(\$arg);
}
return $arg;
};
+
printf "%s\n", $p_turn_root_into_japh->('rootrootrootrootrootroot');
Here's some suggestions on how to shorten it:
- You can get rid of all 'my'
- You don't need $c = $_, either
- You don't need $l=$i++, just use $l, and post-increment at the end
- You don't need an array $::[$l], just use a scalar $::
- You don't need &{$::}, just $:: is enough
- Use the ternary operator to avoid one 'substr'
- You're using a lot of bytes (24) just to represent 24 bits -- convert them to 0x21010.
- Change "\n" into $/ to save space
- Finally, get rid of extra ';' and parentheses everywhere
Now you have 3 lines instead of 6!
print&{sub{$z=$_[0];for((0)x24,qw#8 -6 -4 0 0 14 1 5 -2 7 10 2 0 -1 10
+ 2 6 0 7
19 15 4 10 2#){$::=sub{substr(${$_[0]},($l>23)?$l-24:$l,1)=chr(($l<24&
+&0x21010&
1<<$l)?32:ord(substr ${$_[0]},$l-24,1)-$_)};&$::(\$z);$l++};$z}}(q#roo
+t#x6).$/
|
| [reply] [d/l] [select] |
Great catch! ++
1. You can get rid of all 'my'
2. You don't need $c = $_, either
3. You don't need an array $::$l, just use a scalar $::
Actually, this was because I was calling the subs outside the for on the earlier tries. To use the closures as closures, the 'my's and the $c = $_ are necessary, but in this code there isn't properly a closure. I'll try to play a little more with closures and some ideas I'm brainstorming to a second try...
| [reply] |
| [reply] |
&{
sub {
print @_;
}
}
("hello"," ","world!")
| [reply] [d/l] |
Nice. That $:: gave me an interesting time ;^). Where can I read about it? Grepping perlmod for "::[^a-z]" didn't show me much.
| [reply] |
| [reply] |