Skip to content

Commit f645d86

Browse files
authored
Sync simple cipher (#1025)
[no important files changed]
1 parent 794209f commit f645d86

6 files changed

Lines changed: 127 additions & 98 deletions

File tree

bin/auto-sync.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ scrabble-score
8484
secret-handshake
8585
series
8686
sieve
87+
simple-cipher
8788
space-age
8889
spiral-matrix
8990
square-root

exercises/practice/simple-cipher/.docs/instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Description
1+
# Instructions
22

33
Create an implementation of the [Vigenère cipher][wiki].
44
The Vigenère cipher is a simple substitution cipher.

exercises/practice/simple-cipher/.meta/config.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"camilopayan"
44
],
55
"contributors": [
6-
"MichaelBunker"
6+
"MichaelBunker",
7+
"Narkunan"
78
],
89
"files": {
910
"solution": [
@@ -16,5 +17,7 @@
1617
".meta/example.php"
1718
]
1819
},
19-
"blurb": "Implement a simple shift cipher like Caesar and a more secure substitution cipher"
20+
"blurb": "Implement the Vigenère cipher, a simple substitution cipher.",
21+
"source": "Substitution Cipher at Wikipedia",
22+
"source_url": "https://en.wikipedia.org/wiki/Substitution_cipher"
2023
}

exercises/practice/simple-cipher/.meta/example.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
25-
declare(strict_types=1);
26-
273
class SimpleCipher
284
{
295
public const LETTERS = "abcdefghijklmnopqrstuvwxyz";
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[b8bdfbe1-bea3-41bb-a999-b41403f2b15d]
13+
description = "Random key cipher -> Can encode"
14+
15+
[3dff7f36-75db-46b4-ab70-644b3f38b81c]
16+
description = "Random key cipher -> Can decode"
17+
18+
[8143c684-6df6-46ba-bd1f-dea8fcb5d265]
19+
description = "Random key cipher -> Is reversible. I.e., if you apply decode in a encoded result, you must see the same plaintext encode parameter as a result of the decode method"
20+
21+
[defc0050-e87d-4840-85e4-51a1ab9dd6aa]
22+
description = "Random key cipher -> Key is made only of lowercase letters"
23+
24+
[565e5158-5b3b-41dd-b99d-33b9f413c39f]
25+
description = "Substitution cipher -> Can encode"
26+
27+
[d44e4f6a-b8af-4e90-9d08-fd407e31e67b]
28+
description = "Substitution cipher -> Can decode"
29+
30+
[70a16473-7339-43df-902d-93408c69e9d1]
31+
description = "Substitution cipher -> Is reversible. I.e., if you apply decode in a encoded result, you must see the same plaintext encode parameter as a result of the decode method"
32+
33+
[69a1458b-92a6-433a-a02d-7beac3ea91f9]
34+
description = "Substitution cipher -> Can double shift encode"
35+
36+
[21d207c1-98de-40aa-994f-86197ae230fb]
37+
description = "Substitution cipher -> Can wrap on encode"
38+
39+
[a3d7a4d7-24a9-4de6-bdc4-a6614ced0cb3]
40+
description = "Substitution cipher -> Can wrap on decode"
41+
42+
[e31c9b8c-8eb6-45c9-a4b5-8344a36b9641]
43+
description = "Substitution cipher -> Can encode messages longer than the key"
44+
45+
[93cfaae0-17da-4627-9a04-d6d1e1be52e3]
46+
description = "Substitution cipher -> Can decode messages longer than the key"
Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,8 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
253
declare(strict_types=1);
264

5+
use PHPUnit\Framework\Attributes\TestDox;
276
use PHPUnit\Framework\TestCase;
287

298
class SimpleCipherTest extends TestCase
@@ -33,121 +12,145 @@ public static function setUpBeforeClass(): void
3312
require_once 'SimpleCipher.php';
3413
}
3514

36-
public function testRandomCipherKeyIsLetters(): void
37-
{
38-
$cipher = new SimpleCipher();
39-
$this->assertMatchesRegularExpression('/\A[a-z]+\z/', $cipher->key);
40-
}
41-
4215
/**
4316
* Here we take advantage of the fact that plaintext of "aaa..." doesn't
4417
* output the key. This is a critical problem with shift ciphers, some
4518
* characters will always output the key verbatim.
19+
*
20+
* Uuid: b8bdfbe1-bea3-41bb-a999-b41403f2b15d
4621
*/
47-
public function testRandomKeyCipherEncode(): void
22+
#[TestDox('Random key cipher -> Can encode')]
23+
public function testRandomKeyCipherCanEncode(): void
4824
{
4925
$cipher = new SimpleCipher();
5026
$plaintext = 'aaaaaaaaaa';
5127
$this->assertEquals(substr($cipher->key, 0, 10), $cipher->encode($plaintext));
5228
}
5329

54-
public function testRandomKeyCipherDecode(): void
30+
/**
31+
* Uuid: 3dff7f36-75db-46b4-ab70-644b3f38b81c
32+
*/
33+
#[TestDox('Random key cipher -> Can decode')]
34+
public function testRandomKeyCipherCanDecode(): void
5535
{
5636
$cipher = new SimpleCipher();
5737
$plaintext = 'aaaaaaaaaa';
5838
$this->assertEquals($plaintext, $cipher->decode(substr($cipher->key, 0, 10)));
5939
}
6040

61-
public function testRandomKeyCipherReversible(): void
41+
/**
42+
* Uuid: 8143c684-6df6-46ba-bd1f-dea8fcb5d265
43+
*/
44+
#[TestDox('Random key cipher -> Is reversible')]
45+
public function testRandomKeyCipherIsReversible(): void
6246
{
6347
$cipher = new SimpleCipher();
6448
$plaintext = 'abcdefghij';
6549
$this->assertEquals($plaintext, $cipher->decode($cipher->encode($plaintext)));
6650
}
6751

68-
public function testCipherWithCapsKey(): void
69-
{
70-
$this->expectException(InvalidArgumentException::class);
71-
$cipher = new SimpleCipher('ABCDEF');
72-
}
73-
74-
public function testCipherWithNumericKey(): void
75-
{
76-
$this->expectException(InvalidArgumentException::class);
77-
$cipher = new SimpleCipher('12345');
78-
}
79-
80-
public function testCipherWithEmptyKey(): void
81-
{
82-
$this->expectException(InvalidArgumentException::class);
83-
$cipher = new SimpleCipher('');
84-
}
85-
86-
public function testCipherKeyIsAsSubmitted(): void
52+
/**
53+
* Uuid: defc0050-e87d-4840-85e4-51a1ab9dd6aa
54+
*/
55+
#[TestDox('Random key cipher -> Key is made only of lowercase letters')]
56+
public function testRandomCipherKeyIsLowercaseLetters(): void
8757
{
88-
$cipher = new SimpleCipher('abcdefghij');
89-
$this->assertEquals($cipher->key, 'abcdefghij');
58+
$cipher = new SimpleCipher();
59+
$this->assertMatchesRegularExpression('/\A[a-z]+\z/', $cipher->key);
9060
}
9161

92-
public function testCipherEncode(): void
62+
/**
63+
* Uuid: 565e5158-5b3b-41dd-b99d-33b9f413c39f
64+
*/
65+
#[TestDox('Substitution cipher -> Can encode')]
66+
public function testSubstitutionCipherCanEncode(): void
9367
{
9468
$cipher = new SimpleCipher('abcdefghij');
9569
$plaintext = 'aaaaaaaaaa';
9670
$ciphertext = 'abcdefghij';
9771
$this->assertEquals($ciphertext, $cipher->encode($plaintext));
9872
}
9973

100-
public function testCipherDecode(): void
74+
/**
75+
* Uuid: d44e4f6a-b8af-4e90-9d08-fd407e31e67b
76+
*/
77+
#[TestDox('Substitution cipher -> Can decode')]
78+
public function testSubstitutionCipherCanDecode(): void
10179
{
10280
$cipher = new SimpleCipher('abcdefghij');
10381
$plaintext = 'aaaaaaaaaa';
10482
$ciphertext = 'abcdefghij';
10583
$this->assertEquals($plaintext, $cipher->decode($ciphertext));
10684
}
10785

108-
public function testCipherReversible(): void
86+
/**
87+
* Uuid: 70a16473-7339-43df-902d-93408c69e9d1
88+
*/
89+
#[TestDox('Substitution cipher -> Is reversible')]
90+
public function testSubstitutionCipherIsReversible(): void
10991
{
11092
$cipher = new SimpleCipher('abcdefghij');
11193
$plaintext = 'abcdefghij';
11294
$this->assertEquals($plaintext, $cipher->decode($cipher->encode($plaintext)));
11395
}
11496

115-
public function testDoubleShiftEncode(): void
97+
/**
98+
* Uuid: 69a1458b-92a6-433a-a02d-7beac3ea91f9
99+
*/
100+
#[TestDox('Substitution cipher -> Can double shift encode')]
101+
public function testSubstitutionCipherCanDoubleShiftEncode(): void
116102
{
117103
$cipher = new SimpleCipher('iamapandabear');
118104
$plaintext = 'iamapandabear';
119105
$ciphertext = 'qayaeaagaciai';
120106
$this->assertEquals($ciphertext, $cipher->encode($plaintext));
121107
}
122108

123-
public function testCipherEncodeWrap(): void
109+
/**
110+
* Uuid: 21d207c1-98de-40aa-994f-86197ae230fb
111+
*/
112+
#[TestDox('Substitution cipher -> Can wrap on encode')]
113+
public function testSubstitutionCipherCanWrapEncode(): void
124114
{
125115
$cipher = new SimpleCipher('abcdefghij');
126116
$plaintext = 'zzzzzzzzzz';
127117
$ciphertext = 'zabcdefghi';
128118
$this->assertEquals($ciphertext, $cipher->encode($plaintext));
129119
}
130120

131-
public function testShiftCipherEncode(): void
121+
/**
122+
* Uuid: a3d7a4d7-24a9-4de6-bdc4-a6614ced0cb3
123+
*/
124+
#[TestDox('Substitution cipher -> Can wrap on decode')]
125+
public function testSubstitutionCipherCanWrapDecode(): void
132126
{
133-
$cipher = new SimpleCipher('dddddddddd');
134-
$plaintext = 'aaaaaaaaaa';
135-
$ciphertext = 'dddddddddd';
136-
$this->assertEquals($ciphertext, $cipher->encode($plaintext));
127+
$cipher = new SimpleCipher('abcdefghij');
128+
$plaintext = 'zzzzzzzzzz';
129+
$ciphertext = 'zabcdefghi';
130+
$this->assertEquals($plaintext, $cipher->decode($ciphertext));
137131
}
138132

139-
public function testShiftCipherDecode(): void
133+
/**
134+
* Uuid: e31c9b8c-8eb6-45c9-a4b5-8344a36b9641
135+
*/
136+
#[TestDox('Substitution cipher -> Can encode messages longer than the key')]
137+
public function testSubstitutionCipherCanEncodeMessageLongerThanKey(): void
140138
{
141-
$cipher = new SimpleCipher('dddddddddd');
142-
$plaintext = 'aaaaaaaaaa';
143-
$ciphertext = 'dddddddddd';
144-
$this->assertEquals($plaintext, $cipher->decode($ciphertext));
139+
$cipher = new SimpleCipher('abc');
140+
$cipherText = 'iboaqcnecbfcr';
141+
$plainText = 'iamapandabear';
142+
$this->assertEquals($cipherText, $cipher->encode($plainText));
145143
}
146144

147-
public function testShiftCipherReversible(): void
145+
/**
146+
* Uuid: 93cfaae0-17da-4627-9a04-d6d1e1be52e3
147+
*/
148+
#[TestDox('Substitution cipher -> Can decode messages longer than the key')]
149+
public function testSubstitutionCipherCanDecodeMessageLongerThanKey(): void
148150
{
149-
$cipher = new SimpleCipher('dddddddddd');
150-
$plaintext = 'abcdefghij';
151-
$this->assertEquals($plaintext, $cipher->decode($cipher->encode($plaintext)));
151+
$cipher = new SimpleCipher('abc');
152+
$cipherText = 'iboaqcnecbfcr';
153+
$plainText = 'iamapandabear';
154+
$this->assertEquals($plainText, $cipher->decode($cipherText));
152155
}
153156
}

0 commit comments

Comments
 (0)