如何从Perl中的sub中正确输入和返回单个字母?

时间:2014-04-11 02:25:05

标签: perl encryption split

我正在尝试编写一个代码,该代码将使用基本循环移位密码对字母进行加密,同时保留任何不是字母的字符。我试图通过使用找到每个字母的新值的子来做到这一点。当我现在运行代码时,它会格式化结果,因此每个加密字母之间只有一个空格,而不是保留原始格式。我也无法将结果只用小写字母。

sub encrypter {
        my $letter = shift @_;
        if ($letter =~ m/^[a-zA-Z]/) {
                $letter =~ y/N-ZA-Mn-za-m/A-Za-z/;
                return $letter;
                }
        else {

                return lc($letter);
        }
}
print "Input string to be encrypted: ";
my $input = <STDIN>;
chomp $input;
print "$input   # USER INPUT\n";
my @inputArray = split (//, $input);
my $i = 0;
my @encryptedArray;
for ($i = 0; $i <= $#inputArray; $i++) {
        $encryptedArray[$i] = encrypter($inputArray[$i]);
}
print "@encryptedArray   # OUTPUT\n";

3 个答案:

答案 0 :(得分:2)

您可以尝试更改此行:

if ($letter = m/[^a-zA-Z]/ ) {

更像这样的事情:

if ($letter =~ m/^[a-zA-Z]/) {

在原始行中,您正在对变量$ letter进行赋值,而^将需要在[a-zA-Z]之前进行比较。

答案 1 :(得分:1)

您正在尝试对角色进行rot13翻译。使用tr

可以更轻松地完成此操作
use strict;
use warnings;

sub rot13 {
    my $string = shift;
    $string =~ tr/a-zA-Z/n-zA-Za-m/;
    return $string;
}

print "Input string to be encrypted: ";
chomp(my $input = <STDIN>);

print "$input   # USER INPUT\n";

print "Cycle of 4:\n";

for (1..4) {
    $input = rot13($input);
    print "  $input\n";
}

输出

Input string to be encrypted: asdf
asdf   # USER INPUT
Cycle of 4:
  nFqs
  ASDF
  NfQS
  asdf

答案 2 :(得分:0)

这是一种更为通用的实现方式,它更容易适应类似的东西,例如,为不同的字母使用不同的旋转位置:

#!/usr/bin/perl

use strict;
use warnings;

use feature qw(switch say);

sub rotateBy {
    my ($letter, $rotate_places) = @_;

    $rotate_places = $rotate_places ? $rotate_places : 13;
    my $width = (ord 'z') - (ord 'a') + 1;

    sub rotate {
        my ($let, $base, $places, $width) = @_;
        my $i = (ord $let) - (ord $base);
        return chr((ord $base) + ($i + $places) % $width);
    }

    given ($letter) {
        when (m/[a-z]/) {
            return rotate ($letter, 'a', $rotate_places, $width);
        }
        when (m/A-Z/) {
            return rotate ($letter, 'A', $rotate_places, $width);
        }
        default {
            return $letter;
        }
    }
}

while (<>) {
    chomp;
    print "PLAINTEXT : $_\n";
    print "CIPHERTEXT: ";
    foreach my $let (split //) {
        print rotateBy($let);
    }
    print "\n";
}

顺便说一句,上面的代码看起来太冗长了,也许还有更好的方法。