Добрый день. На пхп пишу кодер/декодер шифра виженера. Ссылка на описание шифра: http://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%84%D1%80_%D0%92%D0%B8%D0%B6%D0%B5%D0%BD%D0%B5%D1%80%D0%B0 Вот что получилось: PHP: <?php $mod = 1; // 1 for cipher, 2 for decipher $text="xxx"; $key="cz"; function vigenere($text, $prekey, $mod) { $len=strlen($text); $res=""; $key=""; $prelen=strlen($prekey); for($i=0; $i<$len;$i++) { $key .= $prekey[$i%$prelen]; } if($mod === 1) { for($i=0; $i<$len; $i++) { $res .= chr((((ord($text[$i])-ord("a"))+(ord($key[$i])-ord("a")))%26)+ord("a")); } } elseif($mod === 2) { for($i=0; $i<$len; $i++) { $res .= chr((((ord($text[$i])-ord("a"))-(ord($key[$i])-ord("a")))%26)+ord("a")); } } return $res; } echo vigenere($text,$key,$mod)."\n"; ?> но не всегда работает правильно. Например, пример из википедии шифруется правильно, а дешифруется неверно. Помогите найти баг, пожалуйста.
BHYCHIK проблема в том, что в ПХП оператор % работает не так как ожидается для отрицательных чисел. Добавьте функцию: PHP: function mymod($val) { return $val < 0 ? $val + 26: $val; } И замените строки: PHP: $res .= chr((((ord($text[$i])-ord("a"))-(ord($key[$i])-ord("a")))%26)+ord("a")); // Заменить на: $res .= chr(mymod(ord($text[$i])-ord($key[$i]))+ord("a"));