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 strict;
|
||||||
use DDG::Goodie;
|
use DDG::Goodie;
|
||||||
|
|
||||||
triggers start => "caesar cipher", "caesar",
|
triggers startend => "caesar cipher",
|
||||||
"ceasar", "ceasar cipher",
|
"ceasar cipher",
|
||||||
"shift cipher";
|
"shift cipher";
|
||||||
|
triggers start => 'caesar', 'ceasar';
|
||||||
|
|
||||||
zci is_cached => 1;
|
zci is_cached => 1;
|
||||||
zci answer_type => "caesar_cipher";
|
zci answer_type => "caesar_cipher";
|
||||||
|
@ -15,9 +16,53 @@ my @alphabet = ('a' ... 'z');
|
||||||
|
|
||||||
my $string_alphabet = join '', @alphabet;
|
my $string_alphabet = join '', @alphabet;
|
||||||
|
|
||||||
handle remainder => sub {
|
sub build_infobox_element {
|
||||||
return unless $_ =~ /(\-?\d+)\s+([[:ascii:]]+)$/;
|
my $query = shift;
|
||||||
my ($shift_val, $to_cipher) = ($1, $2);
|
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;
|
my $amount = $shift_val % 26;
|
||||||
# This creates the cipher by shifting the alphabet.
|
# This creates the cipher by shifting the alphabet.
|
||||||
|
@ -33,6 +78,18 @@ handle remainder => sub {
|
||||||
}
|
}
|
||||||
$result .= $char;
|
$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",
|
return "$result",
|
||||||
structured_answer => {
|
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 answer_type => 'caesar_cipher';
|
||||||
zci is_cached => 1;
|
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 {
|
sub build_structured_answer {
|
||||||
my ($result, $amount, $to_cipher) = @_;
|
my ($result, $amount, $to_cipher) = @_;
|
||||||
return "$result",
|
return "$result",
|
||||||
|
@ -26,6 +47,7 @@ sub build_structured_answer {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub build_test { test_zci(build_structured_answer(@_)) }
|
sub build_test { test_zci(build_structured_answer(@_)) }
|
||||||
|
sub decode_test { test_zci(decode_response()) }
|
||||||
|
|
||||||
ddg_goodie_test(
|
ddg_goodie_test(
|
||||||
[qw( DDG::Goodie::CaesarCipher )],
|
[qw( DDG::Goodie::CaesarCipher )],
|
||||||
|
@ -41,6 +63,15 @@ ddg_goodie_test(
|
||||||
'shift cipher 7 Mxlm mxqm' => build_test('Test text', 7, 'Mxlm mxqm'),
|
'shift cipher 7 Mxlm mxqm' => build_test('Test text', 7, 'Mxlm mxqm'),
|
||||||
'caesar cipher hello' => undef,
|
'caesar cipher hello' => undef,
|
||||||
'caesar cipher' => 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;
|
done_testing;
|
||||||
|
|
Loading…
Reference in New Issue