Winnyのノード文字列復号化プログラム

最近データーベースが楽しいので、Winnyのノードって多いから統計取ったら面白そうだなぁ、と考えながらWinnyの解析について検索。勢いで関係ない上に意味のないプログラムを作成。恐らくは車輪の再開発今は反省している

require 5.8.0;
use strict;
use warnings;
use Crypt::RC4;
use Data::Validate::IP qw(is_public_ipv4 is_private_ipv4 is_ipv4);

###説明#####
#暗号化されたWinnyノード文字列を復号化し、
#出て来たIPを逆引きしたりします。
###########

###使い方###
#予め、Crypt::RC4とData::Validate::IPをCPANよりインストールしてください。
#そして、後述の設定二つを行いperlにぶちこんでください。
############

$| = 1;
our ($crypted_node_list_file, $decrypted_node_list_file);
CONFIG: {#設定
	$crypted_node_list_file = './node.txt';#@から始まるWinnyノードが一行に一つずつ書き込まれているファイル。
	$decrypted_node_list_file = './decrypted_node.txt';#結果を出力するファイル。
}

MAIN: {
	print "start program.\nnode file reading..";
	open(IN, "<$crypted_node_list_file") or die $!;
	my @file = <IN>;
	close(IN);
	chomp @file;
	
	my $all_node = @file;
	print "OK.\n" . $all_node . " lines processing start.\n";
	open(OUT, ">$decrypted_node_list_file") or die $!;
	my %result = (ok_pub=>0, ng_pub=>0, pv=>0, ch=>0, like=>0, chaos=>0);
	foreach my $i (0 .. $#file) {
		my $node = $file[$i];
		print ++$i . "/$all_node line processing..";
		unless ($node =~ /^@/) { print "OK.\n"; next; }
		my $raw = $node;
		$node = pack("H*", substr($node, 1));
		my ($salt, $encrypted) = (substr($node, 0, 1), substr($node, 1));
		$node = RC4($salt . 'piewf6ascxlv', $encrypted);
		if ($node =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d+)$/) {
			my $ip = "$1.$2.$3.$4";
			if (is_public_ipv4($ip)) {#Public IP
				if ($node = gethostbyaddr(pack('C4', $1, $2, $3, $4), 2)) {
					print OUT "$raw -> $node($ip):$5  (Publick IP)";
					$result{ok_pub}++;
				} else { print OUT "$raw -> $ip (Publick IP)"; $result{ng_pub}++; }
			} elsif (is_private_ipv4($ip)) {#Private IP
				print OUT "$raw -> $node (Private IP)";
				$result{pv}++;
			} elsif (is_ipv4($ip)) {#Chaos IP
				print OUT "$raw -> $node (Chaos IP)";
				$result{ch}++;
			} else { print OUT "$raw -> $node (Like IP)"; $result{like}++; }
		} else { print OUT "$raw -> Chaos"; $result{chaos}++; }
		print OUT "\n";
		print "OK.\n";
	}
	print OUT "\n###Result###\ncan translate public ip -> $result{ok_pub}\ncannnot translate public ip -> $result{ng_pub}\n";
	print OUT "private ip -> $result{pv}\nchaos ip -> $result{ch}\nlike ip ->$result{like}\nchaos -> $result{chaos}\n";
	print OUT '############';
	close(OUT);
	print "processing OK.\nprogram end.";
	exit 0;
}
exit 1;

適当なところから持ってきたリストを復号化してみると、Privateアドレス、Globalアドレスという概念が一般?のユーザに広まっていないことが伺えます。
復号化コードを探してみたら、はてな内、しかもPerlで書かれた物があった(2007-01-05 - KENJI’S BLOG)orz
参考になります。ちなみに、僕のスクリプトチェックサムのチェックはしておらず、入力データのチェックも甘いですorz