2015-04-17 61 views
4

我正在玩凱撒密碼,它似乎並沒有工作。凱撒密碼沒有按預期運行

這是我的代碼:

class CaesarCipher { 
    const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
    protected $encrypt_sequence = array(); 
    protected $decrypt_sequence = array(); 

    public function __construct($seed = 1) { 
     $total_chars = strlen(self::CHARS); 
     $seed = $seed % $total_chars; 
     for ($i = 0; $i < $total_chars; $i++) { 
      $src = substr(self::CHARS, $i, 1); 
      $dst = substr(self::CHARS, ($i + $seed) % $total_chars, 1); 
      $this->encrypt_sequence[$src] = $dst; 
      $this->decrypt_sequence[$dst] = $src; 
     } 
     $this->encrypt_sequence[' '] = ' '; 
     $this->decrypt_sequence[' '] = ' '; 
    } 

    public function encrypt($value) { 
     $value = strtoupper($value); 
     return str_replace($this->encrypt_sequence, $this->decrypt_sequence, $value); 
    } 

    public function decrypt($value) { 
     $value = strtoupper($value); 
     return str_replace($this->decrypt_sequence, $this->encrypt_sequence, $value); 
    } 

    public function getEncryptSequence() { 
     return $this->encrypt_sequence; 
    } 

    public function getDecryptSequence() { 
     return $this->decrypt_sequence; 
    } 
} 

運行:

$seed = mt_rand(1, 35); 
$cipher = new CaesarCipher($seed); 
$source = 'THIS IS JUST A TEST WITH 123 NUMBERS'; 
$encrypted = $cipher->encrypt($source); 
$decrypted = $cipher->decrypt($encrypted); 

而且這是我的輸出:

CAESAR CIPHER (seed=16) 

Source: THIS IS JUST A TEST WITH 123 NUMBERS 
Encrypted: X12W 2W 3YWX U XYWX 02X1 567 7Y6VYVW ENCRYPTED :) 
Decrypted: DHIC IC JECD A DECD GIDH LMN NEMBEBC DOES NOT MATCH SOURCE :(


Encryption: A>Q B>R C>S D>T E>U F>V G>W H>X I>Y J>Z K>0 L>1 M>2 N>3 O>4 P>5 Q>6 R>7 S>8 T>9 U>A V>B W>C X>D Y>E Z>F 0>G 1>H 2>I 3>J 4>K 5>L 6>M 7>N 8>O 9>P 
Decryption: Q>A R>B S>C T>D U>E V>F W>G X>H Y>I Z>J 0>K 1>L 2>M 3>N 4>O 5>P 6>Q 7>R 8>S 9>T A>U B>V C>W D>X E>Y F>Z G>0 H>1 I>2 J>3 K>4 L>5 M>6 N>7 O>8 P>9 

誰能給我一個提示,爲什麼它不工作?

+0

您的加密ISN」 t糾正。 –

+0

它有什麼問題? – Cojones

+0

'T'不是轉換爲'9',而是轉換爲'X'。 –

回答

2

Got it!

public function encrypt($value) { 
    $value = strtoupper($value); 
    return strtr($value, $this->encrypt_sequence); 
} 

public function decrypt($value) { 
    $value = strtoupper($value); 
    return strtr($value, $this->decrypt_sequence); 
} 

將正確地en-和解密值。感謝jeroen和GoogleHireMe :)

+0

不錯的,忘記了! – jeroen

3

最明顯的問題是從手動本節上str_replace

注意

更換爲了疑難雜症

由於str_replace()函數替換左到右,它在進行多次替換時可能會替換以前插入的值。另請參閱本文檔中的示例 。

您正在多次替換某些字符並導致您得到的結果。

這適用於加密和解密,所以你不能使用str_replace()與數組來做你想做的事情。

一個可能的解決方案是將字符串逐個加密(解密......),以便每個字符只傳遞一次。

+0

我明白了,謝謝。什麼會更適合呢? – Cojones

+0

@Cojones剛剛添加了最後一段。你可以訪問一個單獨的字符串,就好像你的字符串是一個數組一樣,因此循環它應該很容易。 – jeroen

0

這是一個非常低效的方法,每個str_replace都掃描每個對的整個字符串。相反,爲什麼不掃描輸入字符串並在加密/解密時計算替換值。你問的提示,而不是解決方案......但這裏有一個例子encrypt FUNC(不需要構造,雖然可以存儲而不是把它當作一個參數的構造種子):

public function encrypt($value,$seed) { 
    $n=strlen($value); 
    $nchars=strlen(self::CHARS); 
    for($i=0;$i<$n;$i++) { 
     //This saves you doing the space-space replace, and allows 
     // any chars not in your ciper to remain unmolested 
     $pos=strpos(self::CHARS,$value[$i]); 
     if ($pos>=0) $value[$i]=self::CHARS[($pos+$seed)%$nchars]; 
    } 
} 
+0

這看起來更有效率,但是它比'strtr'更有效率嗎? – Cojones