zeroclickinfo-goodies/lib/DDG/Goodie/CaesarCipher.pm

106 lines
3.0 KiB
Perl
Executable File

package DDG::Goodie::CaesarCipher;
# ABSTRACT: Perform a simple Caesar cipher on some text.
use strict;
use DDG::Goodie;
triggers startend => "caesar cipher",
"ceasar cipher",
"shift cipher";
triggers start => 'caesar', 'ceasar';
zci is_cached => 1;
zci answer_type => "caesar_cipher";
my @alphabet = ('a' ... 'z');
my $string_alphabet = join '', @alphabet;
sub build_infobox_element {
my $query = shift;
my @split = split ' ', $query;
return {
label => $query,
url => 'https://duckduckgo.com/?q=' . (join '+', @split) . '&ia=answer',
};
}
my $infobox = [ { heading => "Example Queries", },
build_infobox_element('caesar cipher 2 text'),
build_infobox_element('shift cipher -2 vgzv'),
build_infobox_element('caesar cipher 33 secret'),
build_infobox_element('caesar cipher -7 zljyla'),
];
my @description_pars = split "\n\n",
share('description.txt')->slurp();
my $decode_response = {
data => {
title => "How to decode the caesar cipher",
infoboxData => $infobox,
description_pars => \@description_pars,
},
meta => {
sourceUrl => 'https://en.wikipedia.org/wiki/Caesar_cipher',
sourceName => 'Wikipedia',
},
templates => {
group => 'info',
options => {
content => 'DDH.caesar_cipher.content',
chompContent => 1,
},
},
};
sub wants_decode {
my $query = shift;
return $query =~ /^how to ((de|en)(code|crypt)|use)( (a|the))?|(de|en)(coder?|crypt(er)?)$/i;
}
sub perform_caesar {
my ($to_cipher, $shift_val) = @_;
my $amount = $shift_val % 26;
# This creates the cipher by shifting the alphabet.
my @shifted_alphabet = (@alphabet[$amount...25],
@alphabet[0..$amount-1]);
my $result;
foreach my $char (split //, $to_cipher) {
if ($char =~ /[[:alpha:]]/) {
my $uppercase = $char =~ /[A-Z]/;
my $idx = index $string_alphabet, lc $char;
$char = $shifted_alphabet[$idx] if ($idx != -1);
$char = uc $char if ($uppercase);
}
$result .= $char;
}
return $result;
}
handle remainder => sub {
my $remainder = shift;
my $wants_decode = wants_decode($remainder);
return "Caesar Cipher", structured_answer => $decode_response if $wants_decode;
return unless $remainder =~ /(\-?\d+)\s+([[:ascii:]]+)$/;
my ($shift_val, $to_cipher) = ($1, $2);
my $result = perform_caesar($to_cipher, $shift_val);
return "$result",
structured_answer => {
data => {
title => "$result",
subtitle => "Caesar cipher $shift_val $to_cipher",
},
templates => {
group => 'text',
moreAt => 0,
},
};
};
1;