我有这段文字:
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
-所以它几乎“复制”了字符串..和解决方案?
答案 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);