in reply to Using a hash to globally s/// a string

I believe part of the problem has to do with quoting metacharacters for the regex (quotemeta). Change:
$source =~ s/$map{$key}/$key/g;

to:

$source =~ s/\Q$map{$key}/$key/g;

UPDATE: Your encryption is broken too. You are making several passes over your input file, globally replacing all characters every time. You need to map each character of your input only once. Don't use global: s///g

for my $line (@source) { chomp $line; my $tmpline = ''; for my $key (split //, $line) { $tmpline .= $map{$key}; } print "$tmpline\n"; }