文字列と排他的論理和

Perlで文字列に対して排他的論理和(xor)などのビット演算が使える事を知りました。


print "abcd" ^ "1234"; # PPPP
print "abcd" & "1234"; # !"#$
print "abcd" | "1234"; # qrst

xorを例にとってみます。
文字列

a b c d
xor 1 2 3 4
P P P P


2進数

01100001 01100010 01100011 01100100
xor 00110001 00110010 00110011 00110100
01010000 01010000 01010000 01010000


xorの習性として、同じ値でxorを2回取ると元に戻るという性質があります。
コレを利用してファイルに簡単な暗号化/復号化を行うスクリプトを書いてみました。

xorfile.pl

if(@ARGV == 2){
	my $BUFFLEN = 4096;
	my $xor = $ARGV[0] x ($BUFFLEN/length($ARGV[0])+1);
	open(my $FH, '<', $ARGV[1]) || die "can't open file ($ARGV[1])";
	binmode($FH);
	binmode(STDOUT);
	my $buff;
	while(my $len = read($FH, $buff, $BUFFLEN)){
		print pack("C*", unpack("C*",$buff ^ substr($xor, 0, $len) ));
	}
	close($FH);
}else{
	print STDERR "usage $0 [xor string] [filename]\n"
}

text.dat

ABCDEFG0123456


perl xorfile.pl "0123456" text.dat > text2.dat
perl xorfile.pl "0123456" text2.dat > text3.dat


text.datとtext3.datは同じデータになります。