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

时间:2019-03-25 07:30:54

标签: php encryption

我有这段文字: abcdzwxy,我想用Atbash method加密他 因此,我创建了一个包含所有字母的数组,并用他的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(按数组)时,将来需要替换{{1 }}到z-所以它几乎“复制”了字符串..和解决方案?

1 个答案:

答案 0 :(得分:1)

您不能在此处使用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);

(代码取自this answer

其余代码大部分相同,但是现在$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);