文本的单字母替换密码(字符串加密)



>我有这段文字: abcdzwxy,我想用 Atbash 方法加密他所以我创建了一个数组,其中包含所有字母,并且对于每个字母,我都用他的Atbash替换。希伯来语中有一个例子:

$text = 'abcdzwxy';
$letters2 = ['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'];
$letters3 = ['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'];
$i = 0;
foreach($letters2 as $l) {
    $text = str_replace($l, $letters3[$i], $text);
    $i++;
}
echo $text;

结果是:abcdabcd而不是zwxyabcd - 因为当它的替换a z(通过数组(它将来需要替换za - 所以它几乎"复制"字符串.. 和解决方案?

您不能在此处使用str_replace(),因为正如您所提到的,当您迭代数组时,它可能会多次替换字符。相反,您应该遍历字符串的字符,并按索引分别替换每个字符。

for ($i = 0; $i < strlen($text); $i++) {
    $text[$i] = $letters3[array_search($text[$i], $letters2)];
}

虽然您可以为字母和替换字符使用两个数组,但我认为关联数组是更适合此任务的结构。

$text = 'abcdzwxy';
$letters2 = ['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'];
$letters3 = ['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'];
$map = array_combine($letters2, $letters3);
for ($i = 0; $i < strlen($text); $i++) {
    $text[$i] = array_search($text[$i], $map);
}
echo $text;

如果字符串包含希伯来语或其他 UTF-8 字符,则无法循环访问它,因为一个字符可能包含多个字节。在这种情况下,您可以使用 preg_split() 创建 UTF-8 字符数组。

$text = preg_split('//u', $text, null, PREG_SPLIT_NO_EMPTY);

(代码取自此答案(

其余代码大致相同,但现在$text是一个数组,必须将其转换回字符串。

function str_to_array($str) {
    return preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
}
$text = "תשר";
$text = str_to_array($text);
$alphabet = str_to_array("אבגדהוזחטיךכלםמןנסעףפץצקרשת");
$map = array_combine($alphabet, array_reverse($alphabet));
for ($i = 0; $i < sizeof($text); $i++) {
    $char = array_search($text[$i], $map);
    if ($char) {
        $text[$i] = $char;
    }
}
$text = implode($text);

最新更新