PHP 凯撒密码函数 str_replace 正在更改字符错误

PHP caesar cipher function str_replace is changing characters wrong

我正在尝试使用 PHP 创建一个凯撒密码函数,但我遇到了 str_replace 的问题。

当我这样做时,

function evangel($data, $key) {
    $alphabet = array('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');

    $cryptoAlphabet = array();

    for($i=0;$i<26;$i++) {
        $index = $i+$key;
        if($i+$key > 25) $index = (($i+$key)%25)-1;

        $cryptoAlphabet[$i] = $alphabet[$index];
    }

    $cryptedData = str_replace($alphabet, $cryptoAlphabet, $data);

    return $cryptedData;
}

它给了我这些数组;

$alphabet = Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f [6] => g [7] => h [8] => i [9] => j [10] => k [11] => l [12] => m [13] => n [14] => o [15] => p [16] => q [17] => r [18] => s [19] => t [20] => u [21] => v [22] => w [23] => x [24] => y [25] => z )

$cryptoAlphabet  = Array ( [0] => b [1] => c [2] => d [3] => e [4] => f [5] => g [6] => h [7] => i [8] => j [9] => k [10] => l [11] => m [12] => n [13] => o [14] => p [15] => q [16] => r [17] => s [18] => t [19] => u [20] => v [21] => w [22] => x [23] => y [24] => z [25] => a ) 

我的 $data = "aacceett" 和 $key = 1;

的输出
aaaaaaaa

但是当我这样做的时候;

function evangel($data, $key) {
    $alphabet = array('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');

    $cryptoAlphabet = array('z','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');

    $cryptedData = str_replace($alphabet, $cryptoAlphabet, $data);

    return $cryptedData;
}

数组是手动声明的,但是这次,例如当我的 $data = "ffddss";

eeccrr

输出正确。为什么当我自动更改字母表数组时 str_replace 功能不起作用?

您的加密字母表在每种情况下都不同。在第一种情况下,[0] 元素是 b,在第二种情况下,z。你的代码产生了它所做的结果,因为 - 例如 - 当它看到 a 时,它用 b 替换它,然后它看到 b 的替换是 c,所以它会这样做,依此类推,直到它遍历整个数组,最终完成用 a 替换 z,所以输出中的所有字符都变成 a。在您的第二种情况下,a 被转换为 z(然后将被转换为 y),但所有其他字符都被替换为数组中较早出现的内容,因此它们不是再次更换。

您可以改用 strtr 解决此问题。 strtrstr_replace 的区别在于 strtr 只会替换给定的子字符串一次。

function evangel($data, $key) {
    $alphabet = range('a', 'z');
    $cryptoAlphabet = array();
    for($i=0;$i<26;$i++) {
        $index = $i+$key;
        if($i+$key > 25) $index = (($i+$key)%25)-1;

        $cryptoAlphabet[$i] = $alphabet[$index];
    }
    $cryptedData = strtr($data, array_combine($alphabet, $cryptoAlphabet));
    return $cryptedData;
}

echo evangel('aacceett', 7);

输出

hhjjllaa

Demo on 3v4l.org

请注意,您可以使用 range.

简化 $alphabet 的定义