4

谁能帮我在 PHP 中修复这个 Vigenere 密码?

很抱歉撕掉了代码,这是我已经剖析了几个小时的地方 - 试图修复!

无论如何,当代码应该输出“Abc”时,它会输出“Ace”。

有一些奇怪的双重偏移,我没有数学大脑来解决!谢谢阅读。

该代码源自AutoHotkey 脚本中的此处- 我已尝试将其转录。网上有 PHP Vigenere 示例(虽然没有在Rosetta Code上,很奇怪!).. 但无论如何,这个被修改为接受小写以及标准大写。谢谢。

  $key = "AAA";
  $keyLength = 3;
  $keyIndex = 0;
  $messageAsArray[0] = "A";
  $messageAsArray[1] = "b";
  $messageAsArray[2] = "c";

  foreach ($messageAsArray as $value)    //Loop through input string array
  {  
      $thisValueASCII = ord($value);
      if ($thisValueASCII >= 65 && $thisValueASCII <= 90) //if is uppercase                                  
      { 
        $thisValueASCIIOffset = 65; 
      }
      else //if is lowercase
      {
        $thisValueASCIIOffset = 97;  
      }
      $thisA = $thisValueASCII - $thisValueASCIIOffset;
      $thisB = fmod($keyIndex,$keyLength);
      $thisC = substr($key, $thisB, 1);
      $thisD = ord($thisC) - 65;
      $thisE = $thisA + $thisD;
      $thisF = fmod($thisE,26);
      $thisG = $thisF + $thisValueASCII  ;
      $thisOutput = chr($thisG); 
      $output = $output . $thisOutput  ; 
      $keyIndex++;
  }
  echo $output
4

1 回答 1

2

好的,我读了你的代码。

你正在编码,你的错误很简单:

$thisG = $thisF + $thisValueASCII  ;

在这一步中,$thisF 是您的加密字母,其值介于 0 和 25 之间。您希望将其打印为 ascii 字符,而不是添加偏移量,而是添加未加密的 ascii 值,这是没有意义的。

你应该有 :

$thisG = $thisF + $thisValueASCIIOffset;

一些提示。您不需要将文本或键作为数组,您可以像使用它一样使用它。

您可以使用 % 运算符代替 fmod。使代码更易于阅读,但这只是个人喜好。

例如 :

$key = "AAA";
$keyLength = strlen($key);
$keyIndex = 0;

$message = str_split("Abc");

$output = '';

foreach($message as $value) // Loop through input string array
{
    $thisValueASCII = ord($value);

    if($thisValueASCII >= 65 && $thisValueASCII <= 90) // if is uppercase
    {
        $thisValueASCIIOffset = 65;
    } else // if is lowercase
    {
        $thisValueASCIIOffset = 97;
    }

    $letter_value_corrected = $thisValueASCII - $thisValueASCIIOffset;
    $key_index_corrected = $keyIndex % $keyLength; // This is the same as fmod but I prefer this notation.

    $key_ascii_value = ord($key[$key_index_corrected]);

    if($key_ascii_value >= 65 && $key_ascii_value <= 90) // if is uppercase
    {
        $key_offset = 65;
    } else // if is lowercase
    {
        $key_offset = 97;
    }

    $final_key = $key_ascii_value - $key_offset;

    $letter_value_encrypted = ($letter_value_corrected + $final_key)%26;

    $output = $output . chr($letter_value_encrypted + $thisValueASCIIOffset);
    $keyIndex++;
}

echo $output;

为您的实施带来乐趣和好运!

于 2013-09-18T16:49:43.237 回答