Merge branch 'master' into add/ciphers/xor_cipher

This commit is contained in:
Rohit Chattopadhyay 2020-10-11 10:58:12 +05:30 committed by GitHub
commit 7bcab5722f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 305 additions and 1 deletions

34
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: PHP Composer
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: composer install --prefer-dist --no-progress --no-suggest
- name: Run PHPUnit
run: composer run-script test

View File

@ -12,7 +12,7 @@ We are very happy that you would consider contributing! As a contributor, you ag
- You did your work - no plagiarism allowed
- Any plagiarized work will not be merged
- Your work will be distributed under [MIT License](License) once your pull request is merged
- Your work will be distributed under [MIT License](LICENSE) once your pull request is merged
- Your submitted work follows (or mostly follows) the styles and standards already found in this repo
**New implementations** are welcome! For example, new solutions for an existing problem, different representations for a graph data structure or an algorithm design with different complexity.

View File

@ -1,4 +1,5 @@
## Ciphers
* [Caesar Cipher](https://github.com/TheAlgorithms/PHP/blob/master/ciphers/caesarCipher.php)
* [Xor Cipher](https://github.com/TheAlgorithms/PHP/blob/master/ciphers/XORCipher.php)
## Searching

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 The Algorithms
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
Maths/AbsoluteMax.php Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* This function calculates
* Absolute max values from
* the different numbers
* provided
*
* @param decimal $numbers A variable sized number input
* @return decimal $absoluteMax Absolute max value
*/
function absolute_max(...$numbers)
{
if (empty($numbers)) {
throw new \Exception('Please pass values to find absolute max value');
}
$absoluteMax = $numbers[0];
for ($loopIndex = 0; $loopIndex < count($numbers); $loopIndex++) {
if ($numbers[$loopIndex] > $absoluteMax) {
$absoluteMax = $numbers[$loopIndex];
}
}
return $absoluteMax;
}

25
Maths/AbsoluteMin.php Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* This function calculates
* Absolute min values from
* the different numbers
* provided.
*
* @param decimal $numbers A variable sized number input
* @return decimal $absoluteMin Absolute min value
*/
function absolute_min(...$numbers)
{
if (empty($numbers)) {
throw new \Exception('Please pass values to find absolute min value');
}
$absoluteMin = $numbers[0];
for ($loopIndex = 0; $loopIndex < count($numbers); $loopIndex++) {
if ($numbers[$loopIndex] < $absoluteMin) {
$absoluteMin = $numbers[$loopIndex];
}
}
return $absoluteMin;
}

29
Maths/CheckPrime.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* This function check whether
* the provided integer is a prime
* number or not.
*
* @param Integer $number An integer input
* @return boolean whether the number is prime or not
*/
function isPrime(int $number)
{
if ($number === 2) {
return true;
}
if ($number % 2 === 0 or $number < 2) {
return false;
}
$i = 3;
while ($i < sqrt($number)) {
if ($number % $i === 0) {
return false;
}
$i += 2;
}
return true;
}

20
Maths/Factorial.php Normal file
View File

@ -0,0 +1,20 @@
<?php
/**
* This function calculates
* and returns the factorial
* of provided positive integer
* number.
*
* @param Integer $number Integer input
* @return Integer Factorial of the input
*/
function factorial(int $number)
{
if ($number < 0) {
throw new \Exception("Negative numbers are not allowed for calculating Factorial");
}
if ($number === 0) {
return 1; // Factorial of 0 is 1
}
return ($number * factorial($number - 1)); // Recursion since x! = x * (x-1)!
}

14
Maths/PerfectSquare.php Normal file
View File

@ -0,0 +1,14 @@
<?php
/**
* This function check whether
* the provided number is a
* perfect square or not.
*
* @param Decimal $number A decimal input
* @return boolean whether the number is perfect square or not
*/
function is_perfect_square($number)
{
$root = (int) sqrt($number);
return (($root * $root) === $number); // If number's square root is an integer then it's a perfect square else not
}

52
ciphers/caesarCipher.php Executable file
View File

@ -0,0 +1,52 @@
<?php
/**
* Encrypt given text using caesar cipher.
* @param string text text to be encrypted
* @param int shift number of shifts to be applied
* @return string new encrypted text
*/
function encrypt(string $text, int $shift): string
{
$encryptedText = ''; // Empty string to store encrypted text
foreach (str_split($text) as $c) { // Going through each character
if (ctype_alpha($c)) {
$placeValue = ord($c) - ord(ctype_upper($c) ? 'A' : 'a'); // Getting value of character (i.e. 0-25)
$placeValue = ($placeValue + $shift) % 26; // Applying encryption formula
$placeValue += ord(ctype_upper($c) ? 'A' : 'a');
$newChar = chr($placeValue); // Getting new character from new value (i.e. A-Z)
$encryptedText .= $newChar; // Appending encrypted character
} else {
$encryptedText .= $c; // Appending the original character
}
}
return $encryptedText; // Returning encrypted text
}
/**
* Decrypt given text using caesar cipher.
* @param string text text to be decrypted
* @param int shift number of shifts to be applied
* @return string new decrypted text
*/
function decrypt(string $text, int $shift): string
{
$decryptedText = ''; // Empty string to store decrypted text
foreach (str_split($text) as $c) { // Going through each character
if (ctype_alpha($c)) {
$placeValue = ord($c) - ord(ctype_upper($c) ? 'A' : 'a'); // Getting value of character (i.e. 0-25)
$placeValue = ($placeValue - $shift) % 26; // Applying decryption formula
if ($placeValue < 0) { // Handling case where remainder is negative
$placeValue += 26;
}
$placeValue += ord(ctype_upper($c) ? 'A' : 'a');
$newChar = chr($placeValue); // Getting new character from new value (i.e. A-Z)
$decryptedText .= $newChar; // Appending decrypted character
} else {
$decryptedText .= $c; // Appending the original character
}
}
return $decryptedText; // Returning decrypted text
}

View File

@ -1,8 +1,14 @@
{
"name" : "thealgorithms/php",
"description": "All Algorithms implemented in PHP",
"license": "MIT",
"require": {
"phan/phan": "^2.7"
},
"require-dev": {
"phpunit/phpunit": "^9"
},
"scripts": {
"test": "vendor/bin/phpunit tests"
}
}

18
tests/CiphersTest.php Executable file
View File

@ -0,0 +1,18 @@
<?php
use function PHPUnit\Framework\assertEquals;
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../ciphers/caesarCipher.php';
class CiphersTest extends TestCase
{
public function testCaesarCipher()
{
assertEquals('Aopz pz h alza.', encrypt('This is a test.', 7));
assertEquals('Aopz pz h alza.', encrypt('This is a test.', 7 + 26));
assertEquals('This is a test.', decrypt('Aopz pz h alza.', 7));
assertEquals('This is a test.', decrypt('Aopz pz h alza.', 7 + 26));
}
}

59
tests/MathTest.php Normal file
View File

@ -0,0 +1,59 @@
<?php
use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertFalse;
use function PHPUnit\Framework\assertTrue;
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../Maths/Factorial.php';
require_once __DIR__ . '/../Maths/CheckPrime.php';
require_once __DIR__ . '/../Maths/AbsoluteMax.php';
require_once __DIR__ . '/../Maths/AbsoluteMin.php';
require_once __DIR__ . '/../Maths/PerfectSquare.php';
class MathTest extends TestCase
{
public function testFactorial()
{
assertEquals(1, factorial(1));
assertEquals(120, factorial(5));
assertEquals(1, factorial(0));
$this->expectException(\Exception::class);
factorial(-25);
}
public function testIsPrime()
{
assertTrue(isPrime(73));
assertFalse(isPrime(21));
assertFalse(isPrime(1));
assertTrue(isPrime(997));
}
public function testAbsoluteMax()
{
assertEquals(50, absolute_max(12, 20, 35, 50, 50, 23));
assertEquals(13, absolute_max(13));
assertEquals(54, absolute_max(12, 13, 54, 22));
$this->expectException(\Exception::class);
absolute_max();
}
public function testAbsoluteMin()
{
assertEquals(12, absolute_min(12, 20, 35, 50, 50, 23));
assertEquals(13, absolute_min(13));
assertEquals(12, absolute_min(12, 13, 54, 22));
$this->expectException(\Exception::class);
absolute_min();
}
public function testPerfectSquare()
{
assertTrue(is_perfect_square(25));
assertFalse(is_perfect_square(43));
assertFalse(is_perfect_square(2));
assertTrue(is_perfect_square(225));
}
}