使用cesar密码

时间:2017-04-24 22:02:43

标签: php arrays encryption encoding caesar-cipher

你好,我将这个练习作为测试的一部分进行叠加,我该如何解决或暗示解决它

/**
 * Class SubstitutionEncodingAlgorithm
 */
class SubstitutionEncodingAlgorithm implements EncodingAlgorithm {

    /**
     * @var array
     */
    private $substitutions;

    /**
     * SubstitutionEncodingAlgorithm constructor.
     * @param $substitutions
     */
    public function __construct(array $substitutions) {
        $this->substitutions = array();
    }

    /**
     * Encodes text by substituting character with another one provided in the pair.
     * For example pair "ab" defines all "a" chars will be replaced with "b" and all "b" chars will be replaced with "a"
     * Examples:
     *      substitutions = ["ab"], input = "aabbcc", output = "bbaacc"
     *      substitutions = ["ab", "cd"], input = "adam", output = "bcbm"
     *
     * @param string $text
     * @return string
     */
    public function encode($text) {
        /**
         * @todo: Implement it
         */
    }

}

到目前为止我在encode()函数中尝试了但是它不起作用,我做错了什么?

public function encode($text) {
    $length = strlen($text);
            $newstr = '';
            for ($i = 0; $i < $length; $i++) {
                if (is_array($this->substitutions) && in_array(strtoupper($text[$i]), array_flip($this->substitutions)))
                    $newstr .= $this->substitutions[strtoupper($text[$i])];
            }


            return $newstr;
        }

据我所知,这是迄今为止实施的cesar算法,任何帮助都会受到赞赏,如何做到这一点

5 个答案:

答案 0 :(得分:1)

您可以使用替换数组并将其拆分为两个数组,例如

$swapA = array();
$swapB = array();

//for each item in the substitutions array take the first char
// and place in swapA and the second/last char and place in swapB
foreach($substitutions as $sub)
{
    $swapA = substr($sub,0,1);
    $swapB = substr($sub,1,1);
}
// the str_replace will replace the all characters in $text chars 
// from position x in swapA with chars in the same position in swapB 

$output = str_replace($swapA, $swapB, $text);

答案 1 :(得分:1)

        $swapA = array();
        $swapB = array();
        $output = '';
        $aText = str_split($text);
        foreach($this->substitutions as $sub)
        {
            $swapA[] = substr($sub,0,1);
            $swapB[] = substr($sub,1,1);

        }

        foreach ($aText as $letter) {
            if (in_array(strtolower($letter, $swapA)) {
                $positionOccurence = array_search ($letter, $swapA);
                $replaced = $swapB[$positionOccurence];
                $output .= str_replace($letter, $replaced, $letter);
            } elseif (in_array(strtolower($letter), $swapB)) {
                $positionOccurence = array_search ($letter, $swapB);
                $replaced = $swapA[$positionOccurence];
                $output .= str_replace($letter, $replaced, $letter);
            } else {
                $output .= $letter;
            }
        }

        return $output;

答案 2 :(得分:0)

我的尝试 - 每个字符文本只有一个字节:

private function encodeText (string $text) : string {

    $result = '';

    for ($i = 0, $e = strlen ($text); $i < $e; $i ++) {
        foreach ($this->substitutions as $substitution) {
            $strpos = strpos ($substitution, $text {$i});
            if ($strpos !== false) {
                $result .= $strpos == 0 ? $substitution {1} : $substitution {0};
                continue 2;
            }
        }

        $result .= $text {$i};
    }

    return $result;
}

其他解决方案更快更简单:

首先在构造函数数组中创建,如:

    foreach ($substitutions as $substitution) {
        $this->substitutions ['from'] .= $substitution {0} . $substitution {1} . strtoupper($substitution {0} . $substitution {1});
        $this->substitutions ['to'] .= $substitution {1} . $substitution {0} . strtoupper($substitution {1} . $substitution {0});
    }

然后简单地进行翻译:

public function encode($text)
{
    return strtr ($text, $this->substitutions ['from'],  $this->substitutions ['to']);
}

答案 3 :(得分:0)

问题是这样的:

public function __construct(array $substitutions) {
    $this->substitutions = array();
}

这是一个空数组。 更改为:

public function __construct(array $substitutions) {
        $this->substitutions = $substitutions;
}

然后测试您的逻辑。

答案 4 :(得分:0)

这是考虑到边缘情况的更精确的答案。

public function encode(string $text): string
{
    $swapA = array();
    $swapB = array();
    $output = '';
    $aText = str_split($text);
    foreach ($this->substitutions as $sub) {
        if (strlen($sub) == 2 && ($sub[0] != $sub[1])) {
            $swapA[] = $sub[0];
            $swapB[] = $sub[1];
        } else {
            throw new InvalidArgumentException ("Must have 2 different characters");
        }
    }

    foreach ($aText as $letter) {
        if (in_array(strtolower($letter), $swapA)) {
            $positionOccurence = array_search($letter, $swapA);
            if (strtolower($letter) != $letter) {
                $replaced = strtoupper($swapB[$positionOccurence]);
            } else {
            $replaced = $swapB[$positionOccurence];
            }
            $output .= str_replace($letter, $replaced, $letter);
        } elseif (in_array(strtolower($letter), $swapB)) {
            $positionOccurence = array_search($letter, $swapB);
            if (strtolower($letter) != $letter) {
                $replaced = strtoupper($swapA[$positionOccurence]);
            } else {
                $replaced = $swapA[$positionOccurence];
            }
            $output .= str_replace($letter, $replaced, $letter);
        } else {
            $output .= $letter;
        }
    }
return $output;
}