ciphergoth: (Default)
[personal profile] ciphergoth
Some of you may remember I posted this a while back:
#!/usr/bin/perl -0777
sub Q{$s[($_[0]+=$_[1])%=@s]}sub S{@s[$x,$y]=@s[$y,$x]}@k=map
hex,pop=~/../g;S Q$y,$k[$x%@k]+Q$x,$_>0for@s=0..255;$x=$y=0;print
chr($_^Q S Q$y,Q$x,1)for unpack'C*',<>

Well I sent it to Adam Back, and he put it online. However, subsequent to that, he sent me another, substantially shorter implementation he and another contributor had done ages ago:
#!/usr/bin/perl -p
INIT{@k=pop=~/../g;$^C=map@s[$w++,$^C]=@s[$^C+=$_+hex$k[$w%@k],$w],@s=0..255}
s#\C#$&^chr$s[255&map{1..$_}@s[$^C,$x]=@s[++$x,$^C+=$s[$x%=@s]]]#eg

This works because the variable $^C is stored in a byte, so half the modular arithmetic is unnecessary. There's a whole bunch of other novel tricks in there, though. Applying these tricks to my version, I get
#!/usr/bin/perl -p
INIT{sub Q{$s[($_[0]+=pop)%=@s]}sub S{@s[$x,$y]=@s[$y,$x]}@k=pop=~/../g;$x+=!!S
Q$y,$_+hex$k[$x%@k]for@s=0..255;$x=$y=0}s/\C/$&^chr Q S Q$y,Q$x,1/eg

which is three characters longer than the version he sent me. Bah!

Can anyone figure out a way to save four characters from this?

Update:
#!/usr/bin/perl -p
INIT{sub Q{$s[($_[0]+=$_[1])%=256]}sub
S{@s[$y,$x++]=@s[$x,$y]}@k=pop=~/../g;S$y=map{S
Q$y,$_+hex$k[$x%@k]}@s=0..255}s/\C/$&^chr Q S Q$y,Q$x/eg

Profile

ciphergoth: (Default)
Paul Crowley

January 2025

S M T W T F S
   1234
5678 91011
12131415161718
19202122232425
262728293031 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 26th, 2025 11:17 am
Powered by Dreamwidth Studios