読者です 読者をやめる 読者になる 読者になる

PHPでシーザー暗号

<?php

/**
 * Caesar暗号を解読するプログラムを作り,暗号を解読してください。暗号鍵(何文字ずらすか)は不明です。
 * 暗号は英文です。
 */

$code = "yWNh'bVVN.hMJfhkURLNhdJ'h'RaaRWPhXWhaQNh.RcN.KJWThdRaQhQN.hXUMN.h'R'aN.HhkURLNI'h'R'aN.hdJ'h.NJMRWPhJhKXXThJWMhkURLNhWXaRLNMhaQJahaQNhKXXThMRMWIahQJcNhJWfhYRLab.N'ihdQRLQhVJMNhkURLNhUX'NhRWaN.N'ahRWhRaHhAQNWhJ'h'QNhUXXTNMhXbahRWaXhaQNhVNJMXdih'QNh'Jdh'XVNaQRWPhcN.fhYNLbURJ.Hh?QNh'JdhJhUJ.PNhdQRaNh.JKKRah.bWWRWPhYJ'ahQN.hUXXTRWPhJahQR'hdJaLQh'JfRWPhIyQhMNJ.hyQhMNJ.hsh'QJUUhKNhaXXhUJaNHIhAQNWhQNhYXYYNMhMXdWhJh.JKKRahQXUNHhkURLNihKNRWPhaQNhLb.RXb'hPR.Uh'QNhdJ'ihOXUUXdNMhaQNh.JKKRahMXdWhaQJahQXUNhJWMhOXbWMhQN.'NUOhRWhJhUJWMhdRaQhVJWfhdXWMN.'HhsahdJ'hJhdXWMN.UJWMHh?QNhVNah'XVNhRWaN.N'aRWPhL.NJab.N'hRWLUbMRWPhaQNhuRWPhJWMh bNNWhXOhrNJ.a'ihaQNhrJaaN.ihJWMhaQNhwJ.LQhrJ.NHh?QNhOXbWMhaQJahVJWfhL.NJab.N'hRWhaQR'hUJWMhMRMWIahQJcNhaQNhKN'ahXOhaNVYN.'hJWMhMRMWIahdJWahaXha.fhaXhQNUYhkURLNhORPb.NhXbahdQN.NhaXhPXhJWMhdQJahaXhMXHhkURLNhJU'XhOXbWMhQN.'NUOhLQJWPRWPh'RgN'hJOaN.hNJaRWPhX.hM.RWTRWPhaQRWP'h'QNhOXbWMHhyWNhVRWbaNh'QNhdJ'hJhONdhRWLQN'haJUUhJWMhaQNhWNeah'QNhdJ'hWRWNhONNahaJUUHhDQNWhkURLNhdJ'hRWhaQR'hUJWMh'QNhNeYNLaNMhaQNhbWNeYNLaNMhJWMhMRMWIahaQRWThVbLQhXOhaQNhbWb'bJUhXLLb..NWLN'Hh?QNhb'NMhQN.hTWXdUNMPNhaXhQNUYhXaQN.hYNXYUNih'bLQhJ'hdQNWh'QNhVJMNh'NW'NhXOhNcRMNWLNhMb.RWPhJha.RJUHhk'hVbLQhJ'hkURLNhaQXbPQahRahRWaN.N'aRWPhKNRWPhdRaQhaQN'Nh'a.JWPNhL.NJab.N'hJWMha.fRWPhaXhPNahJUXWPhdRaQhaQNVih'QNhdXWMN.NMhdQNWh'QNhdXbUMh.Nab.WhQXVNhaXhQN.hWX.VJUhURONhX.hROh'QNhdXbUMHh?QNh.NVNVKN.NMhQN.hLJahJWMhM.NJVNMhXOh'NNRWPhQRVhJPJRWHhlbahdJ'haQN.NhJhdJfhaXhPNahXbahX.hdJ'hRahJUUhSb'ahJhM.NJVj";
$hint = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ .,'?";

$caesar = new Caesar($code, $hint);

//英文なので最も多いのは「 」のはずという仮定をする
echo $caesar->crack($caesar->getShiftNum('h', ' '));

class Caesar {
    private $code;
    private $hint;

    function __construct($code, $hint) {
        $this->code = $code;
        $this->hint = $hint;
    }

    public function getShiftNum($fromChar, $toChar) {
        $fromCharIdx = strpos($this->hint, $fromChar);
        $toCharIdx   = strpos($this->hint, $toChar);

        return $toCharIdx >= $fromCharIdx ? $toCharIdx - $fromCharIdx : ($toCharIdx - $fromCharIdx) * -1;
    }

    public function crack($shift) {
        $key  = $this->createKey($shift);

        $answer = "";
        $code   = $this->code;

        for ($i = 0;$i < mb_strlen($code);$i++) {
            $answer .= $key[$code[$i]];
        }

        return $answer;
    }

    private function createKey($shift) {
        $key = array();
        $hint  = $this->hint;

        $len   = mb_strlen($hint);

        for ($i = 0;$i < $len;$i++) {
            $idx = $i + $shift;
            if ($idx > $len - 1) $idx -= $len;
            $key[$hint[$i]] = $hint[$idx];
        }

        return $key;
    }
}