Simple cipher in php

Hi,

So I’ve munched some and resolved one more test, i.e. all the invalidArgumentExceptions are now working because I’ve followed your advice. I got rid of all the try catch statements and simply threw the errors.

But I’m not passing any of the random key tests. These are the first four tests. I did pass test one previously (code above) and now I’m not anymore. As I understand it, I’m not handling cases in which the class SimpleCipher is created without any argument. I do make a key myself then but I thing I’m not handling the class bit right. I really don’t know.

Could you have a look at my code ? I have added the tests that I’m not passing with commentary underneath.

declare(strict_types=1);

class SimpleCipher
{
    
    public $alphabet = ['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'];

    public function __construct(string $key) {
         $this->ensureKeyIntegrity($key);
    }

    public function ensureKeyIntegrity($key) {
        if(is_string($key)) {
            if(strlen(trim($key)) > 0) {
                $arr = str_split($key); 
                foreach($arr as &$char) { 
                    if(ctype_upper($char)) {
                        echo "All characters must be lower case.\n";
                        throw new InvalidArgumentException("All characters must be lower case.");     
                    }
                    if(is_numeric($char)) {
                        echo "Numbers are not allowed.\n";
                        throw new InvalidArgumentException("Numbers are not allowed.");     
                    }   
                }        
                $this->key = implode($arr);
                return $this->key;
            } 
            else {
                throw new InvalidArgumentException("Empty strings are not allowed.");    
            }       
        } 
        elseif(!$key) {
            $this->key = $this->createNewKey();
        }     
    }

    public function createNewKey() : string {
        $index = rand(0, 25);
        $newkey = $this->alphabet[$index];
        return $newkey;
    }

    public function adjustKeyLength($textArr) {
        $lengteKeys = strlen($this->key);
        $lengteText = count($textArr);
        if($lengteKeys < $lengteText) {
            for($x=0, $aantal = $lengteText - $lengteKeys; $x <= $aantal; $x++) {
                $this->key .= $this->createNewKey();
            }
        } 
    }
    
    public function encode(string $plainText): string  { 
        $arr = str_split($plainText);
        $this->adjustKeyLength($arr);
        $keys = str_split($this->key);
        foreach($arr as $index => &$charact) { 
            $encodingInt = array_search($keys[$index], $this->alphabet);          
            $characterInt = array_search($charact, $this->alphabet); 
            $encodedcharact = $characterInt + $encodingInt;                
            if($encodedcharact > 25 ) {
                $encodedcharact -= 26;
            }
            $charact= $this->alphabet[$encodedcharact];
        }        
        $encodedText = implode($arr);
        echo "encodedText " . $encodedText . "\n";
        return $encodedText;
    }

    public function decode(string $cipherText): string {
        $arr = str_split($cipherText);
        $keys = str_split($this->key);
        foreach($arr as $index => &$charact) { 
            $decodingInt = array_search($keys[$index], $this->alphabet);      
            $characterInt = array_search($charact, $this->alphabet);
            $decodedcharact = $characterInt - $decodingInt;    
            if($decodedcharact < 0 ) {
                $decodedcharact += 26;
            }
            $charact= $this->alphabet[$decodedcharact];
        }   
        $decodedText = implode($arr);        
        echo "decodedText " . $decodedText . "\n";
        return $decodedText;
    }
}

Test 1 : Random cipher key is letters

Code Run

$cipher = new SimpleCipher();
$this->assertMatchesRegularExpression('/\A[a-z]+\z/', $cipher->key);

Test Error

SimpleCipherTest::testRandomCipherKeyIsLetters
ArgumentCountError: Too few arguments to function SimpleCipher::__construct(), 0 passed in SimpleCipherTest.php on line 36 and exactly 1 expected

SimpleCipher.php:32
SimpleCipherTest.php:36

Test 2 Random Key Cipher encode

Code Run

$cipher = new SimpleCipher();
$plaintext = 'aaaaaaaaaa';
$this->assertEquals(substr($cipher->key, 0, 10), $cipher->encode($plaintext));

Test Error

SimpleCipherTest::testRandomKeyCipherEncode
ArgumentCountError: Too few arguments to function SimpleCipher::__construct(), 0 passed in SimpleCipherTest.php on line 47 and exactly 1 expected

SimpleCipher.php:32
SimpleCipherTest.php:47

Test 3 Random Key Cipher decode

Code Run

$cipher = new SimpleCipher();
$plaintext = 'aaaaaaaaaa';
$this->assertEquals(substr($cipher->key, 0, 10), $cipher->encode($plaintext));

Test Error

SimpleCipherTest::testRandomKeyCipherEncode
ArgumentCountError: Too few arguments to function SimpleCipher::__construct(), 0 passed in SimpleCipherTest.php on line 47 and exactly 1 expected

SimpleCipher.php:32
SimpleCipherTest.php:47

Test 4 Random Key Cipher reversible

Code Run

$cipher = new SimpleCipher();
$plaintext = 'abcdefghij';
$this->assertEquals($plaintext, $cipher->decode($cipher->encode($plaintext)));

Test Error

SimpleCipherTest::testRandomKeyCipherReversible
ArgumentCountError: Too few arguments to function SimpleCipher::__construct(), 0 passed in SimpleCipherTest.php on line 61 and exactly 1 expected

SimpleCipher.php:32
SimpleCipherTest.php:61

I think I’m getting close and I would love to solve this.

Thank you and greets,
Karin

Pick one failing test. Say, test 1. What does the test call? What fails when the test does that call? Why does it fail?

1 Like

Hi,

Somehow I’ve passed the tests! I had already passed $key=null as the parameter but I read your post and reread the instructions. I says I have to make a random key of at least 100 characters if there’s no key and I was making a key of only one character. I remembered you writing I wasn’'t encoding ''enough" and the miracle happened!

Thank you so much for hanging in there for me.

Greets,
Karin

1 Like

Congrats on sticking to it and getting it to pass!