I’ve got good news and bad news. The bad news is that I still haven’t finished the book yet. The good news is that I’ve written some Matlab to decode more of the secret messages!

Thanks to an anonymous tip, I learned that the even numbered chapter messages are coded using a Vigenère cipher. Basically, you use a code word to further obfuscate the text so that techniques like frequency analysis (that is, counting how often a letter appears) won’t break the code. That code word is the answer to the previous chapter’s message.

With this new knowledge in hand, I rejiggered (that’s the technical term) my code to decode more of the messages. I still won’t be posting the messages/answers though. Sorry! At least you get chapter 2’s decoded message and answer.

Oh, and try not to use any capitalization or punctuation when typing in the coded text.

% Start fresh
clear
clc

% chapter = 1;
% coded_text = ['yjcv ku vjg pcog qh vjg uauvgo wugf da jco qrgtcvqtu ' ...
%     'vq ocmg htgg rjqpg ecnnu?'];

% Q: what is the name of the system used by ham operators to make 
%     free phone calls?
% A: autopatch

% ========================================================================

chapter = 2;
code_word = 'autopatch';
coded_text = ['wbth lal voe htat oy voe wxbirtn vfzbqt wagye c poh ' ...
    'aeovsn vojgav'];

% Q: What was the name of the central office where I was almost caught?
% A: Pacific Telephone

% ========================================================================
% ========================================================================


% Forwards Alphabet
truth = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', ...
    'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', ...
    'y', 'z'};

% If odd chapter, use rotation cipher
if mod(chapter, 2) == 1
    decoder = truth;
    
    % Loop over the 26 letters of the alphabet
    decoded = cell(1, 26);
    for ii = 1:26
        % Circularly shift the letters
        decoder = {decoder{2:end} decoder{1}};
        
        % Decode the message
        decoded{ii} = coded_text;
        for jj = 1:26
            ind = strfind(coded_text, decoder{jj});
            decoded{ii}(ind) = truth{jj};
        end
        
        % Display the message
        disp([num2str(ii) ' : ' decoded{ii}])
    end
    
% Else, for an even chapter, use Vigenere cipher
else
    
    % Create the truth table
    decoder = cell(26, 26);
    decoder(1, : ) = truth;
    for ii = 2:26
        decoder(ii, : ) = {decoder{ii-1, 2:end}, decoder{ii-1, 1}};
    end
    
    % Variable set up
    nn = 1;
    decoded = coded_text;
    num = 1:26;
    
    % Loop over the message
    for ii = 1:numel(coded_text)
        
        % Skip the char if it's a special character
        if any(strcmp(coded_text(ii), {' ', '"', '!', ','}))
            continue
        end
        
        % Grab the row from the code word
        ind = num(strcmp(decoder(:, 1), code_word(nn)));
        
        % Grab the true letter from the coded text
        decoded(ii) = truth{num(strcmp(decoder(ind, : ), coded_text(ii)))};
        
        % Circularly shift the code word index
        if nn == length(code_word)
            nn = 1;
        else
            nn = nn + 1;
        end
    end
    
    % Display the final decoded message
    disp(decoded)
end
Advertisements