Merge pull request #2642 from duckduckgo/gd/caesar-cipher-trigger-info
CaesarCipher: Add 'How to decode?' responsemaster
commit
0ef3075361
|
@ -4,9 +4,10 @@ package DDG::Goodie::CaesarCipher;
|
|||
use strict;
|
||||
use DDG::Goodie;
|
||||
|
||||
triggers start => "caesar cipher", "caesar",
|
||||
"ceasar", "ceasar cipher",
|
||||
triggers startend => "caesar cipher",
|
||||
"ceasar cipher",
|
||||
"shift cipher";
|
||||
triggers start => 'caesar', 'ceasar';
|
||||
|
||||
zci is_cached => 1;
|
||||
zci answer_type => "caesar_cipher";
|
||||
|
@ -15,9 +16,53 @@ my @alphabet = ('a' ... 'z');
|
|||
|
||||
my $string_alphabet = join '', @alphabet;
|
||||
|
||||
handle remainder => sub {
|
||||
return unless $_ =~ /(\-?\d+)\s+([[:ascii:]]+)$/;
|
||||
my ($shift_val, $to_cipher) = ($1, $2);
|
||||
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 = {
|
||||
id => 'caesar_cipher',
|
||||
name => 'Answer',
|
||||
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.
|
||||
|
@ -33,6 +78,18 @@ handle remainder => sub {
|
|||
}
|
||||
$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 => {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{{#each description_pars}}
|
||||
<p>{{this}}</p>
|
||||
{{/each}}
|
|
@ -0,0 +1,17 @@
|
|||
The Caesar cipher (named after Julius Caesar) is one of the most basic
|
||||
ciphers. It is a form of substitution cipher in which each letter of
|
||||
the alphabet is replaced with another letter a fixed number of places
|
||||
before or after it.
|
||||
|
||||
If you are given the key for a Caesar cipher, then decrypting the
|
||||
message is easy: first take 26 away from the key until you are left
|
||||
with a number between 0 and 25 (add 26 each time for negative keys),
|
||||
then shift each letter by the resulting number in the opposite
|
||||
direction. For example, if you had the text "zljyla", and you knew the
|
||||
key was 33, then taking 26 away from 33 you get 7 - which is between 0
|
||||
and 25. Replacing each letter of the message with that 7 places before
|
||||
it you get the decrypted message "secret".
|
||||
|
||||
If you don't know the key you can perform frequency analysis on the
|
||||
encrypted message or just try every possible key (there's only 26
|
||||
combinations!).
|
|
@ -8,6 +8,27 @@ use DDG::Test::Goodie;
|
|||
zci answer_type => 'caesar_cipher';
|
||||
zci is_cached => 1;
|
||||
|
||||
my $decode_response = {
|
||||
id => 'caesar_cipher',
|
||||
name => 'Answer',
|
||||
data => '-ANY-', # We only need to check it is the right template.
|
||||
meta => {
|
||||
sourceUrl => 'https://en.wikipedia.org/wiki/Caesar_cipher',
|
||||
sourceName => 'Wikipedia',
|
||||
},
|
||||
templates => {
|
||||
group => 'info',
|
||||
options => {
|
||||
content => 'DDH.caesar_cipher.content',
|
||||
chompContent => 1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
sub decode_response {
|
||||
return "Caesar Cipher", structured_answer => $decode_response;
|
||||
}
|
||||
|
||||
sub build_structured_answer {
|
||||
my ($result, $amount, $to_cipher) = @_;
|
||||
return "$result",
|
||||
|
@ -26,6 +47,7 @@ sub build_structured_answer {
|
|||
}
|
||||
|
||||
sub build_test { test_zci(build_structured_answer(@_)) }
|
||||
sub decode_test { test_zci(decode_response()) }
|
||||
|
||||
ddg_goodie_test(
|
||||
[qw( DDG::Goodie::CaesarCipher )],
|
||||
|
@ -41,6 +63,15 @@ ddg_goodie_test(
|
|||
'shift cipher 7 Mxlm mxqm' => build_test('Test text', 7, 'Mxlm mxqm'),
|
||||
'caesar cipher hello' => undef,
|
||||
'caesar cipher' => undef,
|
||||
# Decoding information tests
|
||||
'how to decode a caesar cipher?' => decode_test(),
|
||||
'How to decode a Caesar cipher?' => decode_test(),
|
||||
'how to use a shift cipher' => decode_test(),
|
||||
'how to encrypt the caesar cipher' => decode_test(),
|
||||
'caesar cipher decoder' => decode_test(),
|
||||
'shift cipher encrypter' => decode_test(),
|
||||
'shift cipher decrypt' => decode_test(),
|
||||
'how to decode caesar' => undef,
|
||||
);
|
||||
|
||||
done_testing;
|
||||
|
|
Loading…
Reference in New Issue