php实现playfair
实现 Playfair 加密算法的 PHP 代码
Playfair 是一种经典的对称加密算法,基于 5x5 的字母矩阵进行加密和解密。以下是一个完整的 PHP 实现示例:
<?php
class PlayfairCipher {
private $key;
private $keySquare;
public function __construct($key) {
$this->key = strtoupper($key);
$this->prepareKeySquare();
}
private function prepareKeySquare() {
$key = str_replace('J', 'I', $this->key);
$key = preg_replace('/[^A-Z]/', '', $key);
$key = str_split($key);
$alphabet = range('A', 'Z');
unset($alphabet[array_search('J', $alphabet)]);
$this->keySquare = array_unique(array_merge($key, $alphabet));
$this->keySquare = array_values($this->keySquare);
}
private function getPosition($char) {
$index = array_search($char, $this->keySquare);
return ['row' => (int)($index / 5), 'col' => $index % 5];
}
private function prepareText($text) {
$text = strtoupper($text);
$text = preg_replace('/[^A-Z]/', '', $text);
$text = str_replace('J', 'I', $text);
$result = '';
$len = strlen($text);
for ($i = 0; $i < $len; $i += 2) {
$a = $text[$i];
$b = ($i + 1 < $len) ? $text[$i + 1] : 'X';
if ($a == $b) {
$b = 'X';
$i--;
}
$result .= $a . $b;
}
return $result;
}
public function encrypt($plaintext) {
$text = $this->prepareText($plaintext);
$ciphertext = '';
for ($i = 0; $i < strlen($text); $i += 2) {
$a = $text[$i];
$b = $text[$i + 1];
$posA = $this->getPosition($a);
$posB = $this->getPosition($b);
if ($posA['row'] == $posB['row']) {
$ciphertext .= $this->keySquare[$posA['row'] * 5 + (($posA['col'] + 1) % 5)];
$ciphertext .= $this->keySquare[$posB['row'] * 5 + (($posB['col'] + 1) % 5)];
} elseif ($posA['col'] == $posB['col']) {
$ciphertext .= $this->keySquare[(($posA['row'] + 1) % 5) * 5 + $posA['col']];
$ciphertext .= $this->keySquare[(($posB['row'] + 1) % 5) * 5 + $posB['col']];
} else {
$ciphertext .= $this->keySquare[$posA['row'] * 5 + $posB['col']];
$ciphertext .= $this->keySquare[$posB['row'] * 5 + $posA['col']];
}
}
return $ciphertext;
}
public function decrypt($ciphertext) {
$text = $this->prepareText($ciphertext);
$plaintext = '';
for ($i = 0; $i < strlen($text); $i += 2) {
$a = $text[$i];
$b = $text[$i + 1];
$posA = $this->getPosition($a);
$posB = $this->getPosition($b);
if ($posA['row'] == $posB['row']) {
$plaintext .= $this->keySquare[$posA['row'] * 5 + (($posA['col'] - 1 + 5) % 5)];
$plaintext .= $this->keySquare[$posB['row'] * 5 + (($posB['col'] - 1 + 5) % 5)];
} elseif ($posA['col'] == $posB['col']) {
$plaintext .= $this->keySquare[(($posA['row'] - 1 + 5) % 5) * 5 + $posA['col']];
$plaintext .= $this->keySquare[(($posB['row'] - 1 + 5) % 5) * 5 + $posB['col']];
} else {
$plaintext .= $this->keySquare[$posA['row'] * 5 + $posB['col']];
$plaintext .= $this->keySquare[$posB['row'] * 5 + $posA['col']];
}
}
return $plaintext;
}
}
// 使用示例
$key = "MONARCHY";
$cipher = new PlayfairCipher($key);
$plaintext = "HELLO WORLD";
$encrypted = $cipher->encrypt($plaintext);
$decrypted = $cipher->decrypt($encrypted);
echo "Plaintext: $plaintext\n";
echo "Encrypted: $encrypted\n";
echo "Decrypted: $decrypted\n";
?>
Playfair 算法关键点说明
加密矩阵构建时,字母 'J' 通常被替换为 'I',矩阵由密钥和剩余字母填充,确保每个字母只出现一次。

明文预处理阶段,需要将文本转换为大写,去除非字母字符,处理重复字母对(插入 'X'),并确保文本长度为偶数。
加密规则分为三种情况:同行字母右移、同列字母下移、矩形对角交换。解密则是相反方向移动。

使用注意事项
密钥应选择足够长度且易记的单词或短语,避免使用包含大量重复字母的密钥。
明文中的 'J' 会被自动转换为 'I',解密后需要根据上下文判断是否需要还原为 'J'。
对于短文本或特殊字符,可能需要在加密前后进行额外处理以确保数据完整性。






